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

时间:2017-02-17 07:00:03

标签: c++ windows opencv

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

骨架化二进制图像如下。

input image

2 个答案:

答案 0 :(得分:0)

  1. 首先,您必须在图像上找到所有轮廓(请参阅function cv :: findContours)。
  2. 您必须分析这些轮廓(根据您的要求进行检查)。
  3. P.S。图中的数字绝对不是圆圈。所以我无法确切地说你如何检查收到的轮廓。

答案 1 :(得分:0)

从此图片开始(我删除了边框):

enter image description here

您可以遵循以下方法:

1)使用findContour来获取轮廓。

2)仅保留内部轮廓。你可以检查contourArea(..., true)返回的区域的标志。你将获得2个内部轮廓:

enter image description here

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

enter image description here

这里有完整的参考代码:

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