CV Hough Circle参数检测圆圈

时间:2011-10-12 01:38:29

标签: c opencv geometry

我正试图在斯诺克台球上检测到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;
}

2 个答案:

答案 0 :(得分:2)

我怀疑你在参数太严格或松散时遇到问题。您需要使用参数,直到获得所需的圆圈数。此外,根据图像,高斯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 imagethis是我得到的输出。

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

答案 1 :(得分:0)

如果您使用iOS,则需要包含ios.h,或者只需编写自己的类方法来处理从cvMat到UIImage的img proc,反之亦然。

请原谅这些评论,我将它们仅包括在那些可能发现与我一样的“乱语”研究中的人。每张图片都需要完全不同的设置。不要放弃。 houghcircles是关于那里最好的检测算法。 我将把一些游戏代码与检测相结合,使其更好,更简单,更快。

    #import "JmBViewController.h"

@interface JmBViewController ()

@end

@implementation JmBViewController

- (void)viewDidLoad {
[super viewDidLoad];
_imgtest = [UIImage imageNamed:@"IMG_0424.PNG"];

cv::Mat cvImage;
UIImageToMat(_imgtest, cvImage);
if (!cvImage.empty()) {
    cv::Mat gray;
  //  cv::Mat filteredMat;
    cv::cvtColor(cvImage, gray, CV_BGRA2GRAY);
   // cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.2, 1.2);
    cv::vector<cv::Vec3f> circles;
    //cv::HoughCircles(gray, 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(gray, center, 3, cv::Scalar(0,255,0));
        cv::circle(gray, center, radius, cv::Scalar(0,0,255));
    }
   */

 //  for ( int i = 1; i < 15; i = i + 2 )

        cv::GaussianBlur(gray, gray, cv::Size(9, 9), 1.5, 1.5);

        cv::Mat edges;
        cv::Canny(gray, edges, 0, 50);
        //gray.setTo(cv::Scalar::all(0));
        //gray.setTo(cv::Scalar::all(255), edges);
        cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, gray.rows/30, 100, 50, 10, 30 );
        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(cvImage, center, 5, cv::Scalar::all(200), -1, 8, 0 );//center
            cv::circle(cvImage, center, radius, cv::Scalar::all(255), 3, 8, 0 );//diamter
        NSLog(@"Circles: %ld", i+1);

       // cv::imshow(&"circles i " [ i], gray);
    }


    _imgView.image = MatToUIImage(cvImage);
    }
    /*
cv::Mat cvImage;
cv::Mat grey;
cv::Mat filteredMat;
cv::vector<cv::Vec3f> circles;
// cv::cvtColor(_imgtest, cvImage, CV_BGR2GRAY);
cv::threshold(grey, filteredMat, 100, 255, CV_THRESH_BINARY);
[UIImageCVMatConverter cvMatGrayFromUIImage:_imgtest];
//  cv::cvtColor(cvImage, grey, CV_RGBA2GRAY);
// UIImageToMat(_imgtest, cvImage);
cv::HoughCircles(cvImage, circles, CV_HOUGH_GRADIENT, 1, 50);
//  MatToUIImage(cvImage);
_imgView.image = [UIImageCVMatConverter UIImageFromCVMat:cvImage];
_imgView.image = MatToUIImage(cvImage);
*/

// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*

UIImage* MatToUIImage(const cv::Mat& image) {
NSData *data = [NSData dataWithBytes:image.data length:image.elemSize()*image.total()];
CGColorSpaceRef colorSpace;
if (image.elemSize() == 1) {
    colorSpace = CGColorSpaceCreateDeviceGray();
}else { colorSpace = CGColorSpaceCreateDeviceRGB();
 }
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

CGImageRef imageRef = CGImageCreate(image.cols, image.rows, 8, 8*image.elemSize(), image.step.p[0], colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, FALSE, kCGRenderingIntentDefault);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];

return finalImage;
 }
 */


@end