如何在c ++中使用opencv 3检测图像中的圆圈

Posted

技术标签:

【中文标题】如何在c ++中使用opencv 3检测图像中的圆圈【英文标题】:How to detect the circles in the image using opencv 3 in c++ 【发布时间】:2017-02-17 07:00:03 【问题描述】:

如何检测圆圈并计算此图像中的数字。我是打开 cv 和 c++ 的新手。任何人都可以帮助解决这个问题。我试过用 hough circle 。但是没有用。

骨架化二值图像如下。

【问题讨论】:

我觉得你的问题太笼统了。 寻找轮廓 -> 拟合椭圆 霍夫圆不起作用,呃....首先没有圆。你唯一的赌注是近似值,使用省略号 【参考方案1】:

从这张图片开始(我去掉了边框):

你可以按照这个方法:

1) 使用findContour 获取轮廓。

2) 只保留内部轮廓。您可以检查contourArea(..., true) 返回的区域的符号。您将获得 2 个内部轮廓:

3) 现在你有了两个轮廓,你可以用minEnclosingCircle(蓝色)找到一个圆,或者用fitEllipse(红色)拟合一个椭圆:

这里有完整的代码供参考:

#include <opencv2/opencv.hpp>
#include <vector>

using namespace std;
using namespace cv;

int main() 

    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    // Get contours
    vector<vector<Point>> contours;
    findContours(img, contours, RETR_TREE, CHAIN_APPROX_NONE);

    // Create output image
    Mat3b out;
    cvtColor(img, out, COLOR_GRAY2BGR);

    Mat3b outContours = out.clone();

    // Get internal contours
    vector<vector<Point>> internalContours;
    for (size_t i = 0; i < contours.size(); ++i) 
        // Find orientation: CW or CCW
        double area = contourArea(contours[i], true);
        if (area >= 0) 
            // Internal contour
            internalContours.push_back(contours[i]);

            // Draw with different color
            drawContours(outContours, contours, i, Scalar(rand() & 255, rand() & 255, rand() & 255));
        
    

    // Get circles 
    for (const auto& cnt : internalContours) 
        Point2f center;
        float radius;
        minEnclosingCircle(cnt, center, radius);

        // Draw circle in blue
        circle(out, center, radius, Scalar(255, 0, 0));
    

    // Get ellipses
    for (const auto& cnt : internalContours) 
        RotatedRect rect = fitEllipse(cnt);

        // Draw ellipse in red
        ellipse(out, rect, Scalar(0, 0, 255), 2);
    

    imshow("Out", out);
    waitKey();

    return 0;

【讨论】:

非常感谢您的关心。我试过你的代码。但是我明白了。我无法找到错误。 :(“ConsoleApplication1.exe 中 0x000007FDA3294388 (ucrtbase.dll) 处未处理的异常:将无效参数传递给认为无效参数致命的函数。”此问题发生在 findContours(img, contours, RETR_TREE, CHAIN_APPROX_NONE) 行; 确保您正确加载输入图像(我的答案中的那个,而不是您问题中的那个!)...否则我不知道...这完美适用我的电脑 是的,“右键单击”和“将图像另存为”。尝试从here 是的(3.2,vc14 x86),opencv代码是正确的。您可能有链接问题或其他问题... 我能否知道您在应用程序中使用的库和链接。你使用 c++ API 吗?【参考方案2】:
    首先,您必须找到图像中的所有轮廓(请参阅函数 cv::findContours)。 您必须分析这些轮廓(检查是否符合您的要求)。

附:图片上的数字绝对不是圆形的。所以我不能确切地说你必须如何检查收到的轮廓。

【讨论】:

以上是关于如何在c ++中使用opencv 3检测图像中的圆圈的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Java 改进 OpenCV 中的人脸检测

如何使用 OCR 检测图像中的下标数字?

如何使用 OpenCV Python 检测颜色

如何定义阈值以仅检测图像中的绿色对象:Opencv [重复]

如何在 OpenCV 中使用计算机视觉检测飞镖板上的飞镖? [关闭]

使用Python,OpenCV应用EAST文本检测器检测自然场景图像中的文本