Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 检测红色和绿色圆圈_Python_Opencv_Image Processing - Fatal编程技术网

Python 检测红色和绿色圆圈

Python 检测红色和绿色圆圈,python,opencv,image-processing,Python,Opencv,Image Processing,我想在下图中分别检测红色和绿色圆圈(以及其他一些类似的图片) 我正在使用opencv和python 我尝试过使用houghcircles,但即使在更改参数后也没有任何帮助 任何关于如何做到这一点的建议都会非常有帮助。 如果有人发送您在评论中提到的圆圈大小始终相同的代码,我将不胜感激。 让我们利用这个事实。我的代码片段是用C++语言编写的,但这不应该是个问题,因为它们只是用来显示使用哪个OpenCV函数(以及如何)……/P> TL;DR执行以下操作: 创建典型的圆形图像-模板图像 用于获取所有圆

我想在下图中分别检测红色和绿色圆圈(以及其他一些类似的图片)

我正在使用opencv和python

我尝试过使用houghcircles,但即使在更改参数后也没有任何帮助

任何关于如何做到这一点的建议都会非常有帮助。
如果有人发送您在评论中提到的圆圈大小始终相同的代码,我将不胜感激。 让我们利用这个事实。我的代码片段是用C++语言编写的,但这不应该是个问题,因为它们只是用来显示使用哪个OpenCV函数(以及如何)……/P> TL;DR执行以下操作:

  • 创建典型的圆形图像-模板图像
  • 用于获取所有圆的位置
  • 检查每个圆圈的颜色
  • 现在,让我们开始

    步骤1-模板图像

    您需要一个图像来显示与背景明显分离的圆圈。您有两个选择(两者都同样好):

    • 自己制作这样的图像(如果你知道半径,就计算),或者
    • 只需从正在处理的图像集中取出一张图像,然后裁剪出一个清晰可见的圆圈,并将其另存为一张图像(这就是我所做的,因为这是一个更快的选择)
    圆圈可以是任何颜色-重要的是它与背景不同

    步骤2-模板匹配

    加载图像和模板图像并将其转换为。然后分割通道,以便只能使用饱和通道:

    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;