2

嗨,我正在使用 opencv 进行简单的形状检测检测(三角形、多边形、圆形),这是我的代码:

   int main()
{

    IplImage* img =  cvLoadImage("C:/Users/tarek/Desktop/test5.png");

    //show the original image
    cvNamedWindow("Raw");
    cvShowImage("Raw",img);

    //converting the original image into grayscale
    IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1); 
    IplImage* imgCanny = cvCreateImage(cvGetSize(img), 8, 1); 
    cvCvtColor(img,imgGrayScale,CV_BGR2GRAY);

    //thresholding the grayscale image to get better results
    cvThreshold(imgGrayScale,imgGrayScale,128,255,CV_THRESH_BINARY);  

    CvSeq* contours;  //hold the pointer to a contour in the memory block
    CvSeq* result;   //hold sequence of points of a contour
    CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours

    //finding all contours in the image
    cvFindContours(imgGrayScale, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    //iterating through each contour
    while(contours)
    {
        //obtain a sequence of points of contour, pointed by the variable 'contour'
        result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);

        //if there are 3  vertices  in the contour(It should be a triangle)
        if(result->total==3 )
        {
            //iterating through each point
            CvPoint *pt[3];
            for(int i=0;i<3;i++){
                pt[i] = (CvPoint*)cvGetSeqElem(result, i);
            }

            //drawing lines around the triangle
            cvLine(img, *pt[0], *pt[1], cvScalar(255,0,0),4);
            cvLine(img, *pt[1], *pt[2], cvScalar(255,0,0),4);
            cvLine(img, *pt[2], *pt[0], cvScalar(255,0,0),4);

        }

        //if there are 4 vertices in the contour(It should be a quadrilateral)
        else if(result->total==4 )
        {
            //iterating through each point
            CvPoint *pt[4];
            for(int i=0;i<4;i++){
                pt[i] = (CvPoint*)cvGetSeqElem(result, i);
            }

            //drawing lines around the quadrilateral
            cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
            cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
            cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
            cvLine(img, *pt[3], *pt[0], cvScalar(0,255,0),4);   
        }

        //if there are 7  vertices  in the contour(It should be a heptagon)
        else if(result->total ==7  )
        {
            //iterating through each point
            CvPoint *pt[7];
            for(int i=0;i<7;i++){
                pt[i] = (CvPoint*)cvGetSeqElem(result, i);
            }

            //drawing lines around the heptagon
            cvLine(img, *pt[0], *pt[1], cvScalar(0,0,255),4);
            cvLine(img, *pt[1], *pt[2], cvScalar(0,0,255),4);
            cvLine(img, *pt[2], *pt[3], cvScalar(0,0,255),4);
            cvLine(img, *pt[3], *pt[4], cvScalar(0,0,255),4);
            cvLine(img, *pt[4], *pt[5], cvScalar(0,0,255),4);
            cvLine(img, *pt[5], *pt[6], cvScalar(0,0,255),4);
            cvLine(img, *pt[6], *pt[0], cvScalar(0,0,255),4);
        }

        //obtain the next contour
        contours = contours->h_next; 
    }
    // apply hough circles to find circles and draw a cirlce around it
    cvCanny(imgGrayScale,imgCanny,0,0,3);
    CvSeq* circles = cvHoughCircles(imgCanny,
        storage,
        CV_HOUGH_GRADIENT,
        2,
        imgCanny->height/4,
        200,
        100 );

    for (int 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(0,255,255), 3, 8, 0 );
    }
    //show the image in which identified shapes are marked   
    cvNamedWindow("Tracked");
    cvShowImage("Tracked",img);

    cvWaitKey(0); //wait for a key press

    //cleaning up
    cvDestroyAllWindows(); 
    cvReleaseMemStorage(&storage);
    cvReleaseImage(&img);
    cvReleaseImage(&imgGrayScale);

    return 0;
}

这是输入图像的链接 http://postimage.org/image/fmntii9lb/

以及输出 http://postimage.org/image/4yhodbypj/的另一个链接

我的问题是如何解决中间的两个(也许更多)不必要的大圆圈,当框架中有很多形状时,它们总是会出现提前谢谢

4

0 回答 0