【问题标题】:Detecting small circles with OpenCV (bad image quality)使用 OpenCV 检测小圆圈(图像质量差)
【发布时间】:2012-08-02 17:07:37
【问题描述】:

我正在尝试检测您可以在这张图片的中心看到的四个点: 这个转换为png,我实际上使用的是ppm格式(从相机的原始输出转换后)。实际处理后的图片可用here

我是 opencv 的新手,因此在检测这些点时遇到了很大的问题。这是我迄今为止最好的结果:

如您所见,我检测到了 3 个点,但除此之外,图片中的许多其他东西也被识别为圆圈。

这是代码:

    IplImage* img;
    if((img = cvLoadImage( "photos/img-000012.ppm", 1)) == 0 )
    {
        perror("cvLoadImage");
        return 1;
    }
    cvNamedWindow( "Image view", 1 );
    cvShowImage( "Image view", img );
//  cvWaitKey(0);

    IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 ); // allocate a 1 channel byte image
    CvMemStorage* storage = cvCreateMemStorage(0);
    cvCvtColor( img, gray, CV_BGR2GRAY );
    cvShowImage( "Image view", gray );
//  cvWaitKey(0);

    cvSmooth( gray, gray, CV_GAUSSIAN, 3, 3, 0, 0 );
    cvShowImage( "Image view", gray );
    cvWaitKey(0);

    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT,
            4,      // inverse ratio of the accumulator resolution
            1,      // minimum distance between circle centres
            100,    // higher threshold value for Canny
            20,     // accumulator threshold for the circle centers; smaller->more false circles
            1,  // minimum radius
            10 );   // maximum radius

    printf("circles == %d\n", circles->total);
    int i;
    for (i = 0; i < circles->total; i++) {
        float *p = (float*)cvGetSeqElem(circles, i);
        CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1]));
        CvScalar val = cvGet2D(gray, center.y, center.x);
        if (val.val[0] < 1) continue;
        printf("%d %d %d\n", cvRound(p[0]),cvRound(p[1]), cvRound(p[2]));
        cvCircle(img,  center, cvRound(p[2]),             CV_RGB(0,255,0), 1, CV_AA, 0);
    }
    cvShowImage( "Image view", img );
    cvWaitKey(0);

你知道如何帮助吗?我将不胜感激。我认为人眼很容易发现这些点,所以我希望我可以使用计算机检测它们。

【问题讨论】:

    标签: c opencv computer-vision feature-detection


    【解决方案1】:

    你应该看看this post

    使用我基于它开发的应用程序,我得到了:

    您基本上可以根据您的情况调整此方法并使其更高效: “5。” (“在授予其形状(大小、面积、凸度...”)时验证或使轮廓无效。在您的情况下可能会更加严格,因为您没有圆圈簇。您可以只需映射几乎是perfect circles 的对象。此外,您知道您的圆圈具有相同的大小/相对强度...

    如果有什么不清楚的地方告诉我,

    祝你好运,

    【讨论】:

    • 既然你已经实现了,你认为这种方法在实时系统上可行吗?我们计划在具有 600 MHz 时钟的系统中使用图像识别。我主要考虑自适应阈值,因为它说很耗时。粗略浏览一下,我可以理解你的想法。而且您提供的结果很有希望,一定会尝试做类似的事情。
    • 是的,这可能是可行的,因为 1)您不必为每个迭代/阈值调用函数 cv::adaptiveThreshold(您可以对图像进行卷积,因此您只需设置阈值每一次)。 2) 你可以在灰度下工作。
    【解决方案2】:

    我认为霍夫变换不是最好的情况。或许您可以对它们进行分割并简单地使用它们的颜色和几何参数进行识别。

    【讨论】:

    • 也许吧,但是你可以看到这里的颜色真的很难区分,整个图像看起来几乎像灰度。另外,我不认为我可以依赖几何参数,因为最终我们希望能够检测到散布在整个天花板上的点,所以如果我设置一个固定的,进一步的点会显得更小,因此可以省略 -算法要找到的半径圆。分割它们是什么意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多