首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法使用opencv来检测图像中的相邻圆

有没有办法使用opencv来检测图像中的相邻圆
EN

Stack Overflow用户
提问于 2016-03-22 20:24:03
回答 2查看 809关注 0票数 2

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

请让我知道任何可能的事情来实现这一点。

我使用Hough Circle的代码是:

代码语言:javascript
运行
复制
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;

示例图像为

我想在这里检测到彼此相邻的拨号盘

EN

回答 2

Stack Overflow用户

发布于 2016-03-22 21:14:35

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

此聚类的结果类似于(相同的颜色表示相同的聚类):

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

代码:

代码语言:javascript
运行
复制
#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;
}
票数 4
EN

Stack Overflow用户

发布于 2016-03-22 20:32:27

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

有了这个特定的图像,你可能可以做kmeans和连接的组件。然后倒角匹配圆,并查看连接的组件是否由多个圆组成。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36154312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档