Iphone HoughCircles给出了错误的圈数和位置-iOS

Iphone HoughCircles给出了错误的圈数和位置-iOS,iphone,ios,opencv,image-processing,uiimage,Iphone,Ios,Opencv,Image Processing,Uiimage,我正在使用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,

我正在使用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]];
cv::Mat greyMat;
cv::Mat filteredMat;
向量圆;
cv::CVT颜色(主图像cv、灰色马特、cv_bgr2灰色);
cv::阈值(greyMat,filteredMat,100255,cv_THRESH_BINARY);
对于(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::双边过滤器(过滤器直径、格雷马特、i、i*2、i/2);
}
cv::霍夫圆(格雷马特,圆,cv_-HOUGH_梯度,1,50);
NSLog(@“圆圈:%ld”,圆圈.size());
对于(size_t i=0;i
这段代码返回的结果是我有15个圆圈,它们都位于图像的右侧,这让我感到困惑

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


任何帮助都将不胜感激,提前谢谢

你的算法没有多大意义。看起来您正在迭代使用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);
}
//注意只有psuedocode,不会编译,需要修复。
对于(int i=1;i<31;i=i+2)
{
cv::GaussianBlur(filteredMat,greyMat,cv::Size(i,i),0);
cv::霍夫圆(格雷马特,圆,cv_-HOUGH_梯度,1,50);
对于(size_t i=0;i
要使HoughCircle实现正常工作,仍然需要一些边。它使用了一个精明的边缘检测器,如果你的图像模糊了那么多

此外,我建议您使用双面滤光片,它会模糊,但会尝试保留一些边缘


这也可能有助于定义正确的参数:

以上代码所做的就是反复运行相同的过程,因此您的圆会一次又一次地检测绘制的圆。不是最好的。在我看来,也反复使用高斯模糊,这不是最好的方法。我可以在for循环中看到高斯模糊以使图像更可读,但在for循环中看不到HoughCircles。你需要包括houghcircles中的所有变量,当我全部使用它们时,我的识别率翻了一番

cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, 30, 50, 20, 10, 25);
OpenCV网站上可用的相同格式,它是C++格式。 这是我的iPhone sim卡图片的链接。好市多阿司匹林在我的桌面上。应用程序计算图像中的圆圈数,并在标签中显示总数

这是我的代码,它包含了很多注释,以显示我尝试过的内容…并进行了筛选。希望这有帮助。

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

这一行:

cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
如果括号混乱,则开始时的双“(”)会导致仅使用一个参数而不是两个参数初始化点,它应该是:

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

希望这能有所帮助。

我对hough circles所做的少量工作是,hough circles在二值图像上效果最好,即,一个带有白色像素的图像,显示了要制作圆的边缘点,并遮住了其他所有内容。在您的图像中,您没有传递二值图像。每个像素都作为边缘点工作,因此任何可以画圆的地方。重点是你需要去除图像中的噪声。试着模糊它。好的,但我应该使用哪种类型的模糊?标准化盒滤波器、高斯滤波器、中值滤波器或双边滤波器?哪种对我想做的事情最有效?我应该在灰度化之前或之后去除噪声?