使用GoCV进行黄色小圆检测

huangapple go评论81阅读模式
英文:

Yellow Small Circle Detection Using GoCV

问题

我正在尝试检测带有各种颜色的带有勾号的圆圈。我想要检测的是黄色的圆圈和白色的勾号,将来还想要检测带有红色圆圈和X标记的情况。

我尝试了以下这些代码。这个代码使用了Hough圆检测方法。

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
		}
	}
}

通过一些调整,我设法检测到了一些较大的圆圈,如下所示:

使用GoCV进行黄色小圆检测

但是当我尝试检测较小的圆圈时,没有成功。

使用GoCV进行黄色小圆检测

以下是我编写的用于隔离颜色的代码。我所做的是从一定的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()

	gocv.CvtColor(img, &hsv_img, gocv.ColorBGRToHSV)
	img_rows, img_cols := hsv_img.Rows(), hsv_img.Cols()

	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 {
		window2.IMShow(original_image)
		window3.IMShow(lower_bound)
		window4.IMShow(upper_bound)

		if window.WaitKey(10) >= 0 {
			break
		}
	}
}

这是结果。上面的代码只能检测到一个红色圆圈(应该是两个)和一个黄色圆圈。

使用GoCV进行黄色小圆检测

我一直在尝试将Python中的轮廓检测转换为GoCV,但遇到了令人困惑的GoCV API。我在希望GoCV和OpenCV社区能够帮助我正确检测小而多彩的圆圈。非常感谢您的建议。

英文:

I'm trying to detect circle with checkmark with variety of colours. What I want to detect is yellow with white checkmark, and in the future red circle with x mark. 使用GoCV进行黄色小圆检测使用GoCV进行黄色小圆检测使用GoCV进行黄色小圆检测

What I've been trying so far are these codes below. This one using Hough Circles method.

package main

import (
	&quot;fmt&quot;
	&quot;image&quot;
	&quot;image/color&quot;
	&quot;os&quot;

	&quot;gocv.io/x/gocv&quot;
)

func DetectCircles() {
	if len(os.Args) &lt; 2 {
		fmt.Println(&quot;How to run:\n\tfind-circles [imgfile]&quot;)
		return
	}

	filename := os.Args[1]

	grey_window := gocv.NewWindow(&quot;grey window&quot;)
	grey_window.MoveWindow(600, 0)
	window := gocv.NewWindow(&quot;detected circles&quot;)
	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, &amp;img, gocv.ColorBGRToGray)

	gocv.MedianBlur(img, &amp;img, 5)

	circles := gocv.NewMat()
	defer circles.Close()

	gocv.HoughCirclesWithParams(
		img,
		&amp;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 &lt; circles.Cols(); i++ {
		v := circles.GetVecfAt(0, i)
		// if circles are found
		if len(v) &gt; 2 {
			x := int(v[0])
			y := int(v[1])
			r := int(v[2])

			gocv.Circle(&amp;original_img, image.Pt(x, y), r, green, 2)
			gocv.Circle(&amp;original_img, image.Pt(x, y), 2, red, 3)
		}
	}

	for {
		window.IMShow(original_img)

		if window.WaitKey(10) &gt;= 0 {
			break
		}
	}
}

With some adjustment, I manage to detect some bigger circles like these.
使用GoCV进行黄色小圆检测

But still no luck when I try with smaller circle.
使用GoCV进行黄色小圆检测

These are the codes I wrote to isolate the colour. What I did was adding some colour mask from and to certain HSV range.

package main

import (
	&quot;fmt&quot;
	&quot;image&quot;
	&quot;image/color&quot;
	&quot;os&quot;

	&quot;gocv.io/x/gocv&quot;
)

func DetectCircles2() {
	if len(os.Args) &lt; 2 {
		fmt.Println(&quot;How to run:\n\tgo run . [imgfile]&quot;)
		return
	}

	filename := os.Args[1]

	window := gocv.NewWindow(&quot;detected colors&quot;)
	window2 := gocv.NewWindow(&quot;end result&quot;)
	window3 := gocv.NewWindow(&quot;lower bound&quot;)
	window4 := gocv.NewWindow(&quot;upper bound&quot;)
	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, &amp;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, &amp;yellow_mat, gocv.ColorBGRToHSV)
	// hsv := gocv.Split(yellow_mat)
	// fmt.Printf(&quot;H: %d S: %d V: %d\n&quot;, hsv[0].GetUCharAt(0, 0), hsv[1].GetUCharAt(0, 0), hsv[2].GetUCharAt(0, 0))

	gocv.CvtColor(img, &amp;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, &amp;lower_bound)
	gocv.InRange(hsv_img, lb2, ub2, &amp;upper_bound)

	gocv.AddWeighted(lower_bound, 1.0, upper_bound, 1.0, 0.0, &amp;color_isolated_img)
	gocv.GaussianBlur(color_isolated_img, &amp;color_isolated_img, image.Pt(9, 9), 2, 2, gocv.BorderDefault)

	gocv.HoughCirclesWithParams(
		color_isolated_img,
		&amp;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 &lt; circles.Cols(); i++ {
		v := circles.GetVecfAt(0, i)
		fmt.Println(v)
		if len(v) &gt; 2 {
			x := int(v[0])
			y := int(v[1])
			r := int(v[2])

			gocv.Circle(&amp;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) &gt;= 0 {
			break
		}
	}
}

Here is the result. Code above only manage to detect one red circle (it's supposed to be two) and one yellow circle.
使用GoCV进行黄色小圆检测

I've been trying to convert contour detection written in python only to stumble to confusing gocv API. I'm tagging gocv and opencv in hope these two communities would help me to properly detect small colourful circles. Any advice will be appreciated. Thank you very much.

答案1

得分: 0

所以我所做的是安装了一个名为gcv的库,由vcaesar开发。其中有一个名为FindAllImg的方法,我只需要提供两个图像,一个是源图像(在我的情况下是屏幕截图),另一个是需要在截图中搜索的模板图像。

英文:

So what I did was I installing another library that's called gcv by vcaesar. There was a method called FindAllImg and what I need just provide two image, one is the source image, in my case a screenshot, and the other is a template image that needed to be searched in the screenshot.

huangapple
  • 本文由 发表于 2022年3月27日 03:44:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/71631287.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定