CV霍夫圆参数检测圈 [英] CV Hough Circle Parameters to detect Circles

查看:243
本文介绍了CV霍夫圆参数检测圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检测的台球桌22球。我有一个形象来测试,但程序OS检测其他2球,和随机圆。我的code下面是圆检测算法。有谁知道哪些参数应进行调整,以获得检测我需要?谢谢

 的#include< cv.h>
#包括LT&;&highgui.h GT;
#包括LT&;&math.h中GT;INT主(INT ARGC,字符** argv的)
{INT edge_thresh = 1;
    * IplImage的IMG = cvLoadImage(C:\\\\ \\\\用户\\\\弥敦道桌面\\\\ SnookerPic.png,1);;
    * IplImage的灰= cvCreateImage(cvGetSize(IMG),8,1);
     * IplImage的边缘= cvCreateImage(cvSize(img->宽度,img->高度),8,1);
    CvMemStorage *存储= cvCreateMemStorage(0);
    cvCvtColor(IMG,灰色,CV_BGR2GRAY);
    cvThreshold(灰色,灰色,CV_GAUSSIAN,9,9);
    cvSmooth(灰色,灰色,CV_GAUSSIAN,11,11);
    cvCanny(灰色,边缘,(浮点)edge_thresh,(浮点)edge_thresh * 3,5);
    CvSeq *圈= cvHoughCircles(边,存储,
        CV_HOUGH_GRADIENT,2,20,200,50);
    INT I;    对于(i = 0; I< circles-个总,我++)
    {
         浮* P =(浮点*)cvGetSeqElem(圈,我);
         cvCircle(IMG,cvPoint(cvRound(P [0]),cvRound(第[1])),
             3,CV_RGB(0,255,0),-1,8,0);
         cvCircle(IMG,cvPoint(cvRound(P [0]),cvRound(第[1])),
             cvRound(第[2]),CV_RGB(255,0,0),3,8,0);
    }
    cvNamedWindow(圈,1);
    cvShowImage(圈子,IMG);
    返回0;
}


解决方案

我怀疑你有与参数是不是太严格还是宽松的麻烦。你需要,直到你得到你想要的圈数与参数玩。此外,高斯模糊11×11可以根据图像上有点咄咄逼人。对于我的形象,它是做弊大于利,但我的形象是一种理想化的...

我修改你正在使用包括轨道的酒吧让您与康力参数玩OpenCV的例子。这应该真正帮助你得到它是如何工作的感觉。此外,要注意minDist参数。对于我的形象,圆的圆心分别约为32像素的路程。你需要调整这个你圈子的大小。所以,这里是示例:

 的#include< opencv2 /核心/ core.hpp>
#包括LT&; opencv2 / highgui / highgui.hpp>
#包括LT&; opencv2 / imgproc / imgproc.hpp>使用命名空间的简历;INT HI = 1,LO = 1;INT主(INT ARGC,CHAR *的argv []){
    垫原稿= imread(Snooker_balls_triangled.png);
    INT键= 0;    namedWindow(圈,1);
    createTrackbar(喜,圆,&安培;喜,255);
    createTrackbar(LO,圆,&安培;不料,255);    做
    {
        //更新显示和斯诺克,所以我们可以和他们一起玩
        垫显示= orig.clone();        太斯诺克;
        cvtColor(原稿,桌球,CV_RGB2GRAY);        矢量< Vec3f>界;        //还美元,这里卤味门槛p $ pventing崩溃...
        HoughCircles(斯诺克,圆,CV_HOUGH_GRADIENT,2,32.0,喜大于0喜:1,LO大于0 LO:1);
        用于(为size_t我= 0; I< circles.size();我++)
        {
             点中心(cvRound(圈[I] [0]),cvRound(圈[I] [1]));
             INT半径= cvRound(圈[I] [2]);             //绘制绿色圆圈中心
             圆(显示,中心,3个,标量(0,255,0),-1,8,0);             //绘制蓝色圆圈轮廓
             圆(显示器,圆心,半径标量(255,0,0),3,8,0);
        }        imshow(圈子,显示器);
        imshow(斯诺克,斯诺克);
        键= waitKey(33);
    }而((char)的关键= 27!);
    返回0;
}

我用这个斯诺克图片和的是输出我得到的。

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

I am trying to detect 22 balls on the snooker table. I have an image to test on but programme os detecting 2 balls, and random circles elsewhere. My code is below with the circle detection algorithm. Does anyone know which parameters should be adjusted to get the detection i would need? thanks

#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;
}

解决方案

I suspect you are having trouble with the parameters being either too restrictive or loose. You need to play with the parameters until you get the number of circles you want. Also, the Gaussian 11x11 blur may be a bit aggressive depending on the image. For my image, it was doing more harm than good, but my image is kind of idealized...

I modified the OpenCV example you are using to include the track bars allowing you to play with the Canny parameters. This should really help you get a feel for how it works. Also, pay attention to the minDist parameter. For my image, the circle centers were about 32 pixels away. You'll need to adjust this to your circle sizes. So, here is the sample:

#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;
}

I used this snooker image, and this is the output I get.

(P.S. consider using the C++ interface it's far superior to the C interface IMHO :)

这篇关于CV霍夫圆参数检测圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆