【问题标题】:Is there any way to detect adjacent circles in image using opencv有没有办法使用opencv检测图像中的相邻圆圈
【发布时间】:2016-03-22 12:24:02
【问题描述】:

我正在尝试检测图像中的相邻圆圈。这些可以是4或5。有什么方法可以在opencv中检测到它。我尝试了很多方法,包括霍夫圆法。但我也在检测额外的圆圈。如果在任何情况下我能够检测到圆形,那么相同的参数将不适用于其他图像。

请告诉我任何可能实现此目的的方法。

我使用霍夫圆的代码是:

Mat img, gray;
img = imread("/Users/Development/Desktop/Images/IMG_0297.jpg");
cvtColor(img, gray, CV_BGR2GRAY);
// smooth it, otherwise a lot of false circles may be detected
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2, gray.rows/16,80,100,30,50 );
for( size_t i = 0; i < circles.size(); i++ )
{
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    // draw the circle center
    circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
    // draw the circle outline
    circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
waitKey(0);
return 0;

示例图片是

我想检测其中相邻的表盘

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    您可以使用partition 对相邻圆的圆进行聚类,即中心距离与其半径的 sim 相似的圆。您只需要定义适当的等价谓词,这里在CirclesOnSameLine 中实现。您最终可以改进此谓词,以仅将具有相似半径的圆视为相等。

    这种聚类的结果是这样的(相同的颜色意味着相同的聚类):

    使用这种方法,您可以安全地检测到一些圆,因为您可以删除不属于超过 4-5 个圆的集群的圆。

    代码:

    #include <opencv2/opencv.hpp>
    #include <vector>
    using namespace cv;
    using namespace std;
    
    struct CirclesOnSameLine
    {
        float _tolerance;
    
        CirclesOnSameLine(float tolerance) : _tolerance(tolerance) {};
    
        bool operator()(const Vec3f& lhs, const Vec3f& rhs)
        {
            // [0] = x
            // [1] = y
            // [2] = radius
            float center_distance = sqrt((lhs[0] - rhs[0])*(lhs[0] - rhs[0]) + (lhs[1] - rhs[1])*(lhs[1] - rhs[1]));
            float sum_radii = lhs[2] + rhs[2];
    
            if (sum_radii > center_distance)
            {
                return (sum_radii / center_distance) < _tolerance;
            }
            return (center_distance / sum_radii) < _tolerance;
        }
    };
    
    
    int main()
    {
        Mat3b img = imread("path_to_image");
    
        Mat1b gray;
        cvtColor(img, gray, COLOR_BGR2GRAY);
    
        GaussianBlur(gray, gray, Size(9, 9), 2, 2);
        vector<Vec3f> circles;
        HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2, gray.rows / 16, 80, 100, 10, 100);
    
        // Cluster circles near each other
        vector<int> labels;
        int n_labels = partition(circles, labels, CirclesOnSameLine(1.1f));
    
        vector<Scalar> colors;
        for (int i = 0; i < n_labels; ++i)
        {
            Scalar color(rand() & 255, rand() & 255, rand() & 255);
            colors.push_back(color);
        }
    
        Mat3b adjacent = img.clone();
        for (size_t i = 0; i < circles.size(); i++)
        {
            Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            // draw the circle outline
            circle(adjacent, center, radius, colors[labels[i]], 3, 8, 0);
        }
    
        // Remove small clusters
        vector<int> count(labels.size(), 0);
        for (size_t i = 0; i < labels.size(); ++i)
        {
            count[labels[i]]++;
        }
    
        Mat3b big_clusters = img.clone();
        for (size_t i = 0; i < circles.size(); i++)
        {
            if (count[labels[i]] < 4) continue;
    
            Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            // draw the circle outline
            circle(big_clusters, center, radius, Scalar(0, 0, 255), 3, 8, 0);
        }
    
    
    
        imshow("Adjacent circles", adjacent);
        imshow("Adjacent circles", big_clusters);
    
        waitKey();
    
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      例如,您可以对圆进行倒角匹配,然后使用边缘检测和图像扫描检查圆是否与另一个圆共享边缘或靠近它,以查看圆是否足够接近以相邻.

      使用这个特定的图像,您可能可以做 kmeans 和连接的组件。然后倒角匹配圆,看看一个连通的组件是否由多个圆组成。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      • 2011-12-25
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多