CV Hough Circle参数检测圆

标签 c opencv geometry

我正在尝试检测斯诺克 table 上的 22 个球。我有一张图像要测试,但程序 os 检测 2 个球,以及其他地方的随机圆圈。我的代码在圆检测算法下面。有谁知道应该调整哪些参数以获得我需要的检测?谢谢

#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char** argv)
{   int edge_thresh = 1;
    IplImage* img = cvLoadImage("C:\\Users\\Nathan\\Desktop\\SnookerPic.png", 1);;
    IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1);
     IplImage *edge = cvCreateImage( cvSize(img->width,img->height), 8, 1);
    CvMemStorage* storage = cvCreateMemStorage(0);
    cvCvtColor(img, gray, CV_BGR2GRAY);
    cvThreshold(gray,gray, CV_GAUSSIAN, 9, 9);
    cvSmooth(gray, gray, CV_GAUSSIAN, 11, 11); 
    cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 5);
    CvSeq* circles = cvHoughCircles(edge, storage, 
        CV_HOUGH_GRADIENT, 2, 20, 200, 50);
    int i;

    for (i = 0; i < circles->total; i++) 
    {
         float* p = (float*)cvGetSeqElem( circles, i );
         cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 
             3, CV_RGB(0,255,0), -1, 8, 0 );
         cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 
             cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
    }
    cvNamedWindow( "circles", 1 );
    cvShowImage( "circles", img );


    return 0;
}

最佳答案

我怀疑您遇到了参数过于严格或过于宽松的问题。您需要调整参数,直到获得所需的圆圈数。此外,根据图像的不同,高斯 11x11 模糊可能有点激进。对于我的形象,弊大于利,但我的形象有点理想化......

我修改了您正在使用的 OpenCV 示例,以包含允许您使用 Canny 参数的轨迹栏。这真的可以帮助您了解它的工作原理。另外,请注意 minDist 参数。对于我的图像,圆心距离大约 32 像素。您需要根据您的圆圈大小进行调整。所以,这里是示例:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int hi = 1, lo = 1;

int main(int argc, char* argv[]) {
    Mat orig = imread("Snooker_balls_triangled.png");
    int key = 0;

    namedWindow("circles", 1);
    createTrackbar("hi", "circles", &hi, 255);
    createTrackbar("lo", "circles", &lo, 255);

    do
    {
        // update display and snooker, so we can play with them
        Mat display = orig.clone();

        Mat snooker;
        cvtColor(orig, snooker, CV_RGB2GRAY);

        vector<Vec3f> circles;

        // also preventing crash with hi, lo threshold here...
        HoughCircles(snooker, circles, CV_HOUGH_GRADIENT, 2, 32.0, hi > 0 ? hi : 1, lo > 0 ? lo : 1 );
        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 green circle center
             circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 );

             // draw the blue circle outline
             circle( display, center, radius, Scalar(255,0,0), 3, 8, 0 );
        }

        imshow( "circles", display );
        imshow("snooker", snooker);
        key = waitKey(33);
    } while((char)key != 27);
    return 0;
}

我用了这个snooker image , 和 this是我得到的输出。

(P.S. 考虑使用 C++ 接口(interface),它远优于 C 接口(interface)恕我直言 :)

关于CV Hough Circle参数检测圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7734377/

相关文章:

c - 动态 C - 使用 writeUserBlockArray() 时出错

python - 向灰度图像添加颜色叠加

wpf - 增加StrokeThickness,但保持Path的尺寸

geometry - 如何确定圆弧的弧形截面(即扇形切片)中是否包含点(X,Y)?

OpenCV 理解灰度

python - 如何从 findHomography 获取旋转角度?

C - 结构中的动态数组 - 重新分配后崩溃

C动态内存/C字符串

c - 并发进程的 FIFO 问题

python - 使用开放式CV在Python中进行背景提取