使用 GoCV 进行黄色小圆圈检测
Yellow Small Circle Detection Using GoCV
我正在尝试检测带有各种颜色复选标记的圆圈。我要检测的是带有白色复选标记的黄色,以及将来带有 x 标记的红色圆圈。
到目前为止,我一直在尝试以下这些代码。这个使用霍夫圆法。
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
func DetectCircles() {
if len(os.Args) < 2 {
fmt.Println("How to run:\n\tfind-circles [imgfile]")
return
}
filename := os.Args[1]
grey_window := gocv.NewWindow("grey window")
grey_window.MoveWindow(600, 0)
window := gocv.NewWindow("detected circles")
defer grey_window.Close()
defer window.Close()
original_img := gocv.IMRead(filename, gocv.IMReadColor)
defer original_img.Close()
img := gocv.NewMat()
defer img.Close()
gocv.CvtColor(original_img, &img, gocv.ColorBGRToGray)
gocv.MedianBlur(img, &img, 5)
circles := gocv.NewMat()
defer circles.Close()
gocv.HoughCirclesWithParams(
img,
&circles,
gocv.HoughGradient,
1, // dp
// float64(img.Rows()/8), // minDist
26,
200, // param1
48, // param2
0, // minRadius
0, // maxRadius
)
green := color.RGBA{0, 255, 0, 0}
red := color.RGBA{255, 0, 0, 0}
for i := 0; i < circles.Cols(); i++ {
v := circles.GetVecfAt(0, i)
// if circles are found
if len(v) > 2 {
x := int(v[0])
y := int(v[1])
r := int(v[2])
gocv.Circle(&original_img, image.Pt(x, y), r, green, 2)
gocv.Circle(&original_img, image.Pt(x, y), 2, red, 3)
}
}
for {
window.IMShow(original_img)
if window.WaitKey(10) >= 0 {
break
}
}
}
经过一些调整,我设法检测到一些像这样的更大的圆圈。
但是当我尝试使用更小的圆圈时仍然没有成功。
这些是我写的用来隔离颜色的代码。我所做的是在特定的 HSV 范围内添加一些颜色遮罩。
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
func DetectCircles2() {
if len(os.Args) < 2 {
fmt.Println("How to run:\n\tgo run . [imgfile]")
return
}
filename := os.Args[1]
window := gocv.NewWindow("detected colors")
window2 := gocv.NewWindow("end result")
window3 := gocv.NewWindow("lower bound")
window4 := gocv.NewWindow("upper bound")
window2.MoveWindow(600, 0)
window3.MoveWindow(0, 600)
window4.MoveWindow(600, 600)
defer window.Close()
defer window2.Close()
defer window3.Close()
defer window4.Close()
img := gocv.IMRead(filename, gocv.IMReadColor)
defer img.Close()
original_image := img.Clone()
defer original_image.Close()
gocv.MedianBlur(img, &img, 3)
hsv_img := gocv.NewMat()
defer hsv_img.Close()
// yellow := gocv.NewScalar(0, 255, 255, 0)
// yellow_mat := gocv.NewMatFromScalar(yellow, gocv.MatTypeCV8UC3)
// gocv.CvtColor(yellow_mat, &yellow_mat, gocv.ColorBGRToHSV)
// hsv := gocv.Split(yellow_mat)
// fmt.Printf("H: %d S: %d V: %d\n", hsv[0].GetUCharAt(0, 0), hsv[1].GetUCharAt(0, 0), hsv[2].GetUCharAt(0, 0))
gocv.CvtColor(img, &hsv_img, gocv.ColorBGRToHSV)
img_rows, img_cols := hsv_img.Rows(), hsv_img.Cols()
// lb1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(0.0, 208.0, 94.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
// ub1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(179.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lb1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(20.0, 50.0, 50.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
ub1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(40.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lb2 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(155.0, 100.0, 100.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
ub2 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(180.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lower_bound := gocv.NewMat()
upper_bound := gocv.NewMat()
color_isolated_img := gocv.NewMat()
circles := gocv.NewMat()
defer lower_bound.Close()
defer upper_bound.Close()
defer color_isolated_img.Close()
defer circles.Close()
gocv.InRange(hsv_img, lb1, ub1, &lower_bound)
gocv.InRange(hsv_img, lb2, ub2, &upper_bound)
gocv.AddWeighted(lower_bound, 1.0, upper_bound, 1.0, 0.0, &color_isolated_img)
gocv.GaussianBlur(color_isolated_img, &color_isolated_img, image.Pt(9, 9), 2, 2, gocv.BorderDefault)
gocv.HoughCirclesWithParams(
color_isolated_img,
&circles,
gocv.HoughGradient,
1,
float64(color_isolated_img.Rows()/8),
100,
20,
0,
0,
)
green := color.RGBA{0, 255, 0, 0}
for i := 0; i < circles.Cols(); i++ {
v := circles.GetVecfAt(0, i)
fmt.Println(v)
if len(v) > 2 {
x := int(v[0])
y := int(v[1])
r := int(v[2])
gocv.Circle(&original_image, image.Pt(x, y), r, green, 2)
}
}
for {
// window.IMShow(color_isolated_img)
window2.IMShow(original_image)
window3.IMShow(lower_bound)
window4.IMShow(upper_bound)
if window.WaitKey(10) >= 0 {
break
}
}
}
这是结果。上面的代码只能检测到一个红色圆圈(应该是两个)和一个黄色圆圈。
我一直在尝试转换用 python 编写的轮廓检测只是为了迷惑 gocv API。我正在标记 gocv 和 opencv,希望这两个社区能帮助我正确检测彩色小圆圈。任何建议将被认真考虑。非常感谢。
所以我所做的是安装另一个由 vcaesar 称为 gcv 的库。有一个方法叫做FindAllImg,我只需要提供两张图片,一张是源图,在我的例子中是截图,另一张是需要在截图中搜索的模板图片。
我正在尝试检测带有各种颜色复选标记的圆圈。我要检测的是带有白色复选标记的黄色,以及将来带有 x 标记的红色圆圈。
到目前为止,我一直在尝试以下这些代码。这个使用霍夫圆法。
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
func DetectCircles() {
if len(os.Args) < 2 {
fmt.Println("How to run:\n\tfind-circles [imgfile]")
return
}
filename := os.Args[1]
grey_window := gocv.NewWindow("grey window")
grey_window.MoveWindow(600, 0)
window := gocv.NewWindow("detected circles")
defer grey_window.Close()
defer window.Close()
original_img := gocv.IMRead(filename, gocv.IMReadColor)
defer original_img.Close()
img := gocv.NewMat()
defer img.Close()
gocv.CvtColor(original_img, &img, gocv.ColorBGRToGray)
gocv.MedianBlur(img, &img, 5)
circles := gocv.NewMat()
defer circles.Close()
gocv.HoughCirclesWithParams(
img,
&circles,
gocv.HoughGradient,
1, // dp
// float64(img.Rows()/8), // minDist
26,
200, // param1
48, // param2
0, // minRadius
0, // maxRadius
)
green := color.RGBA{0, 255, 0, 0}
red := color.RGBA{255, 0, 0, 0}
for i := 0; i < circles.Cols(); i++ {
v := circles.GetVecfAt(0, i)
// if circles are found
if len(v) > 2 {
x := int(v[0])
y := int(v[1])
r := int(v[2])
gocv.Circle(&original_img, image.Pt(x, y), r, green, 2)
gocv.Circle(&original_img, image.Pt(x, y), 2, red, 3)
}
}
for {
window.IMShow(original_img)
if window.WaitKey(10) >= 0 {
break
}
}
}
经过一些调整,我设法检测到一些像这样的更大的圆圈。
但是当我尝试使用更小的圆圈时仍然没有成功。
这些是我写的用来隔离颜色的代码。我所做的是在特定的 HSV 范围内添加一些颜色遮罩。
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
func DetectCircles2() {
if len(os.Args) < 2 {
fmt.Println("How to run:\n\tgo run . [imgfile]")
return
}
filename := os.Args[1]
window := gocv.NewWindow("detected colors")
window2 := gocv.NewWindow("end result")
window3 := gocv.NewWindow("lower bound")
window4 := gocv.NewWindow("upper bound")
window2.MoveWindow(600, 0)
window3.MoveWindow(0, 600)
window4.MoveWindow(600, 600)
defer window.Close()
defer window2.Close()
defer window3.Close()
defer window4.Close()
img := gocv.IMRead(filename, gocv.IMReadColor)
defer img.Close()
original_image := img.Clone()
defer original_image.Close()
gocv.MedianBlur(img, &img, 3)
hsv_img := gocv.NewMat()
defer hsv_img.Close()
// yellow := gocv.NewScalar(0, 255, 255, 0)
// yellow_mat := gocv.NewMatFromScalar(yellow, gocv.MatTypeCV8UC3)
// gocv.CvtColor(yellow_mat, &yellow_mat, gocv.ColorBGRToHSV)
// hsv := gocv.Split(yellow_mat)
// fmt.Printf("H: %d S: %d V: %d\n", hsv[0].GetUCharAt(0, 0), hsv[1].GetUCharAt(0, 0), hsv[2].GetUCharAt(0, 0))
gocv.CvtColor(img, &hsv_img, gocv.ColorBGRToHSV)
img_rows, img_cols := hsv_img.Rows(), hsv_img.Cols()
// lb1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(0.0, 208.0, 94.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
// ub1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(179.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lb1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(20.0, 50.0, 50.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
ub1 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(40.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lb2 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(155.0, 100.0, 100.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
ub2 := gocv.NewMatWithSizeFromScalar(gocv.NewScalar(180.0, 255.0, 255.0, 0.0), img_rows, img_cols, gocv.MatTypeCV8UC3)
lower_bound := gocv.NewMat()
upper_bound := gocv.NewMat()
color_isolated_img := gocv.NewMat()
circles := gocv.NewMat()
defer lower_bound.Close()
defer upper_bound.Close()
defer color_isolated_img.Close()
defer circles.Close()
gocv.InRange(hsv_img, lb1, ub1, &lower_bound)
gocv.InRange(hsv_img, lb2, ub2, &upper_bound)
gocv.AddWeighted(lower_bound, 1.0, upper_bound, 1.0, 0.0, &color_isolated_img)
gocv.GaussianBlur(color_isolated_img, &color_isolated_img, image.Pt(9, 9), 2, 2, gocv.BorderDefault)
gocv.HoughCirclesWithParams(
color_isolated_img,
&circles,
gocv.HoughGradient,
1,
float64(color_isolated_img.Rows()/8),
100,
20,
0,
0,
)
green := color.RGBA{0, 255, 0, 0}
for i := 0; i < circles.Cols(); i++ {
v := circles.GetVecfAt(0, i)
fmt.Println(v)
if len(v) > 2 {
x := int(v[0])
y := int(v[1])
r := int(v[2])
gocv.Circle(&original_image, image.Pt(x, y), r, green, 2)
}
}
for {
// window.IMShow(color_isolated_img)
window2.IMShow(original_image)
window3.IMShow(lower_bound)
window4.IMShow(upper_bound)
if window.WaitKey(10) >= 0 {
break
}
}
}
这是结果。上面的代码只能检测到一个红色圆圈(应该是两个)和一个黄色圆圈。
我一直在尝试转换用 python 编写的轮廓检测只是为了迷惑 gocv API。我正在标记 gocv 和 opencv,希望这两个社区能帮助我正确检测彩色小圆圈。任何建议将被认真考虑。非常感谢。
所以我所做的是安装另一个由 vcaesar 称为 gcv 的库。有一个方法叫做FindAllImg,我只需要提供两张图片,一张是源图,在我的例子中是截图,另一张是需要在截图中搜索的模板图片。