【问题标题】:Adjust code to detect multiple circles instead of just 1 in OPENCV调整代码以检测多个圆圈,而不是 OPENCV 中的 1 个圆圈
【发布时间】:2011-09-30 23:54:53
【问题描述】:

我已经让这个圆圈检测工作,但只检测到 1 个圆圈。我将如何调整代码以检测多个圆圈(将检测到的最大圆圈为 22 个,因为它用于斯诺克)。我想我会编辑圆形检测方法,但我被卡住了:(

#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <math.h>
#include <string.h>
#include <conio.h>

using namespace std;

IplImage* img = 0;
CvMemStorage * cstorage;
CvMemStorage * hstorage;

void detectCircle( IplImage *frame );


int main( int argc, char **argv )
{
    CvCapture *capture = 0;
    IplImage  *frame = 0;
    int       key = 0;

    hstorage = cvCreateMemStorage( 0 );
    cstorage = cvCreateMemStorage( 0 );

    //CvVideoWriter *writer = 0;
    //int colour = 1;
    //int fps = 25;
    //int frameW = 640;
    //int frameH = 480;
    //writer = cvCreateVideoWriter("test.avi",CV_FOURCC('P', 'I', 'M', '1'),fps,cvSize(frameW,frameH),colour);

    //initialise camera
    capture = cvCaptureFromCAM( 0 );

    //check if camera present
    if ( !capture )
    {
        fprintf( stderr, "cannot open webcam\n");
        return 1;
    }

    //create a window
    cvNamedWindow( "Snooker", CV_WINDOW_AUTOSIZE );

    while(key !='q') 
    {

    //get frame
        frame = cvQueryFrame(capture);
        //int nFrames = 50;
        //for (int i=0; i<nFrames;i++){
            //cvGrabFrame(capture);
            //frame = cvRetrieveFrame(capture);
            //cvWriteFrame(writer, frame);
        //}

    //check for frame
        if( !frame ) break;

        detectCircle(frame);


    //display current frame
        //cvShowImage ("Snooker", frame );

        //exit if Q pressed
        key = cvWaitKey( 20 );

    }
    // free memory
    cvDestroyWindow( "Snooker" );
    cvReleaseCapture( &capture );
    cvReleaseMemStorage( &cstorage);
    cvReleaseMemStorage( &hstorage);
    //cvReleaseVideoWriter(&writer);

    return 0;
}

**void detectCircle( IplImage * img )
{
    int px;
    int py;
    int edge_thresh = 1;
    IplImage *gray = cvCreateImage( cvSize(img->width,img->height), 8, 1);
    IplImage *edge = cvCreateImage( cvSize(img->width,img->height), 8, 1);

    cvCvtColor(img, gray, CV_BGR2GRAY);

    gray->origin = 1;

    // color threshold
cvThreshold(gray,gray,100,255,CV_THRESH_BINARY);    

// smooths out image
cvSmooth(gray, gray, CV_GAUSSIAN, 11, 11);

// get edges
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 5); 

// detects circle
CvSeq* circle =  cvHoughCircles(gray, cstorage, CV_HOUGH_GRADIENT, 1, gray->height/50, 5, 35);

// draws circle and its centerpoint
float* p = (float*)cvGetSeqElem( circle, 0 );
if( p==null ){ return;}
cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(255,0,0), -1, 8, 0 );
cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(200,0,0), 1, 8, 0 );
px=cvRound(p[0]); 
py=cvRound(p[1]);**



cvShowImage ("Snooker", img );
}

【问题讨论】:

    标签: opencv detection geometry


    【解决方案1】:

    您的代码找到所有圆圈 - 您只需画一个:

    // draws circle and its centerpoint
    float* p = (float*)cvGetSeqElem( circle, 0 );
    if( p==null ){ return;}
    cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(255,0,0), -1, 8, 0 );
    cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(200,0,0), 1, 8, 0);
    px=cvRound(p[0]); 
    py=cvRound(p[1]);
    

    您应该循环执行,例如:

    for( int i=0; i < circles->total; i++ ) 
    {
        float* p = (float*) cvGetSeqElem( circles, i );
        // ... d draw staff
    }
    

    【讨论】:

    • 谢谢。有效。它绘制了它检测到的所有圆圈,这些圆圈看起来相当随机。你不知道我将如何使圆检测部分更准确。我到处都是圈子。再次感谢
    • 抱歉回复晚了 - 首先,我认为您应该将最小距离设置为比球的最小半径大一点(但这不是您遇到问题的原因)。其次,您的最后两个参数是高阈值 - 第一个是 Canny 算法,第二个是检测中心点。因此,您应该将它们设置得更大(例如,尝试将它们设置为 100 之类的值)。并添加另外两个参数 - 用于圆的最小和最大半径。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多