Python 检测红色和绿色圆圈
我想在下图中分别检测红色和绿色圆圈(以及其他一些类似的图片) 我正在使用opencv和python 我尝试过使用houghcircles,但即使在更改参数后也没有任何帮助 任何关于如何做到这一点的建议都会非常有帮助。Python 检测红色和绿色圆圈,python,opencv,image-processing,Python,Opencv,Image Processing,我想在下图中分别检测红色和绿色圆圈(以及其他一些类似的图片) 我正在使用opencv和python 我尝试过使用houghcircles,但即使在更改参数后也没有任何帮助 任何关于如何做到这一点的建议都会非常有帮助。 如果有人发送您在评论中提到的圆圈大小始终相同的代码,我将不胜感激。 让我们利用这个事实。我的代码片段是用C++语言编写的,但这不应该是个问题,因为它们只是用来显示使用哪个OpenCV函数(以及如何)……/P> TL;DR执行以下操作: 创建典型的圆形图像-模板图像 用于获取所有圆
如果有人发送您在评论中提到的圆圈大小始终相同的代码,我将不胜感激。 让我们利用这个事实。我的代码片段是用C++语言编写的,但这不应该是个问题,因为它们只是用来显示使用哪个OpenCV函数(以及如何)……/P> TL;DR执行以下操作:
- 自己制作这样的图像(如果你知道半径,就计算),或者
- 只需从正在处理的图像集中取出一张图像,然后裁剪出一个清晰可见的圆圈,并将其另存为一张图像(这就是我所做的,因为这是一个更快的选择)
using namespace std;
using namespace cv;
Mat im_rgb = imread("circles.jpg");
Mat tm_rgb = imread("template.jpg");
Mat im_hsv, tm_hsv;
cvtColor(im_rgb, im_hsv, CV_RGB2HSV);
cvtColor(tm_rgb, tm_hsv, CV_RGB2HSV);
vector<Mat> im_channels, tm_channels;
split(im_hsv, im_channels);
split(tm_hsv, tm_channels);
这就是获得的图像和模板上的圆的外观:
现在,执行模板匹配。我建议您选择计算归一化相关系数的模板匹配类型:
Mat match_result;
matchTemplate(image_input, template_input, match_result, CV_TM_CCOEFF_NORMED);
这是模板匹配结果:
此图像告诉您,如果将模板放置在图像上的不同位置,模板与基础图像的关联程度如何。例如,像素(0,0)处的结果值对应于输入图像上放置在(0,0)处的模板
当模板放置在与基础图像匹配良好的位置时,相关系数较高。使用阈值法放弃除信号峰值以外的所有内容(模板匹配的值将位于[-1,1]间隔内,您只对接近1的值感兴趣):
接下来,确定模板结果最大值在每个隔离区域内的位置。为此,我建议您使用阈值图像作为遮罩。每个区域内只需选择一个最大值
这些位置告诉您必须将模板放置在何处,以使其与圆最匹配。我画的矩形从这些点开始,宽度/高度与模板图像相同:
步骤3:圆圈的颜色
现在您知道了模板应该放置在哪里,以便它们能够很好地覆盖圆。但是您仍然需要找出圆心在模板图像上的位置。您可以通过计算模板饱和通道的质心来实现这一点:
using namespace std;
using namespace cv;
Mat im_rgb = imread("circles.jpg");
Mat tm_rgb = imread("template.jpg");
Mat im_hsv, tm_hsv;
cvtColor(im_rgb, im_hsv, CV_RGB2HSV);
cvtColor(tm_rgb, tm_hsv, CV_RGB2HSV);
vector<Mat> im_channels, tm_channels;
split(im_hsv, im_channels);
split(tm_hsv, tm_channels);
在图像上,圆心位于以下点:
Point circ_center_on_image = template_position + circ_center_on_template;
现在,您只需检查这些点处的红色通道强度是否大于绿色通道强度。如果是,圆圈为红色,否则为绿色:
在这种情况下,简单的颜色分割也会产生良好的效果。圆圈大小的可能重复总是相同的(图像内和图像间)?圆圈内的颜色是恒定的?@Mika是的,圆圈的大小是相同的,但在将图像转换到HSV颜色空间后,会出现绿色和红色的阴影分割……谢谢Necj。这帮了大忙
Point circ_center_on_image = template_position + circ_center_on_template;