【问题标题】:HoughCircles gives wrong number of circles and position - iOSHoughCircles 给出了错误的圈数和位置 - iOS
【发布时间】:2013-05-23 16:16:36
【问题描述】:

我正在使用 OpenCV 帮助我检测从 iPhone 相机拍摄的图像中的硬币。我使用 HoughCircles 方法帮助我找到它们,但结果不太理想。

cv::Mat greyMat;
    cv::Mat filteredMat;
    cv::vector<cv::Vec3f> circles;
    cv::cvtColor(mainImageCV, greyMat, CV_BGR2GRAY);

    cv::threshold(greyMat, filteredMat, 100, 255, CV_THRESH_BINARY);

    for ( int i = 1; i < 31; i = i + 2 )
    {
//        cv::blur( filteredMat, greyMat, cv::Size( i, i ), cv::Point(-1,-1) );
        cv::GaussianBlur(filteredMat, greyMat, cv::Size(i,i), 0);
//        cv::medianBlur(filteredMat, greyMat, i);
//        cv::bilateralFilter(filteredMat, greyMat, i, i*2, i/2);
    }

    cv::HoughCircles(greyMat, circles, CV_HOUGH_GRADIENT, 1, 50);

    NSLog(@"Circles: %ld", circles.size());

    for(size_t i = 0; i < circles.size(); i++)
    {
        cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
        int radius = cvRound(circles[i][2]);
        cv::circle(greyMat, center, 3, cv::Scalar(0,255,0));
        cv::circle(greyMat, center, radius, cv::Scalar(0,0,255));
    }

    [self removeOverViews];
    [self.imageView setImage: [self UIImageFromCVMat:greyMat]];

当前的代码段返回我有 15 个圆圈,并且所有位置都在图像的右侧,这让我感到困惑。

我是 OpenCV 的新手,几乎没有任何 iOS 示例让我绝望。

任何帮助将不胜感激,在此先感谢!

【问题讨论】:

  • 我对霍夫圆所做的少量工作是霍夫圆在二值图像上效果最好,即具有白色像素的图像显示要制作圆的边缘点,并且把其他一切都涂黑。在您的图像中,您没有传递二进制图像。每个像素都作为边缘点,因此可以在任何地方制作一个圆圈。
  • 重点是需要去除图像中的噪点。尝试模糊它。
  • 好的,但是我应该使用哪种类型的模糊?归一化盒滤波器、高斯滤波器、中值滤波器还是双边滤波器?哪个对我想做的事情最有效?
  • 我应该在将其变灰之前消除噪音吗?还是之后?

标签: iphone ios opencv image-processing uiimage


【解决方案1】:

您的算法没有多大意义。似乎您正在迭代地使用 cv::GaussianBlur,但是当您在其上运行 HoughCircles 时,它只会处理已由带有 31x31 内核的 GassianBlur 过滤的灰色图像,这将使废话变得模糊图片。做这样的事情来看到最好的结果可能更有意义:

这将迭代地向您显示所有图像,我相信这是您最初想要做的。

// NOTE only psuedocode, won't compile, need to fix up.
for ( int i = 1; i < 31; i = i + 2 )
{
    cv::GaussianBlur(filteredMat, greyMat, cv::Size(i,i), 0);
    cv::HoughCircles(greyMat, circles, CV_HOUGH_GRADIENT, 1, 50);

    for(size_t i = 0; i < circles.size(); i++)
    {
        cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
        int radius = cvRound(circles[i][2]);
        cv::circle(greyMat, center, 3, cv::Scalar(0,255,0));
        cv::circle(greyMat, center, radius, cv::Scalar(0,0,255));
    }
    cv::imshow("Circles i " + i, greyMat);
}

您仍然需要一些优势才能使 HoughCircle 实现正常工作。它使用 Canny 边缘检测器,如果您将图像模糊得那么厉害。

另外,我建议您使用双边过滤器,它会模糊但会尝试保留一些边缘。

这也可能有助于定义正确的参数:HoughCircles Parameters to recognise balls

【讨论】:

    【解决方案2】:

    上述代码所做的只是一遍又一遍地运行相同的过程,因此您的圆圈会一遍又一遍地检测绘制的圆圈。不是最好的。在我看来,也一遍又一遍地使用高斯模糊,这不是最好的方法。我可以在 for 循环中看到高斯模糊以使图像更具可读性,但在 for 循环中看不到 HoughCircles。您需要将所有变量都包含在 houghcircles 中,当我全部使用它们时,它的识别率提高了一倍。

    cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, 30, 50, 20, 10, 25);
    

    与 opencv 网站上提供的格式相同,它是 C++ 格式。

    这是我的 iPhone sim pic 的链接。我桌面上的 Costco 阿司匹林。应用计算图像中的圆圈并在标签中显示总数。

    这是我的代码,其中包含很多 cmets 以显示我尝试过的内容......并进行了筛选。希望这可以帮助。 OpenCV install in xcode

    【讨论】:

      【解决方案3】:

      我知道这是一个老问题,所以把它放在这里以防其他人会犯同样的错误(就像我一样......):

      这一行:

      cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
      

      括号弄乱了,开头的双“((”导致该点仅使用一个参数而不是两个参数进行初始化,应该是:

      cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
      

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-22
        相关资源
        最近更新 更多