Ask Your Question
0

Cannot detect yellow balls using OpenCV

asked 2014-10-30 10:49:28 -0600

MohZ gravatar image

updated 2015-09-30 11:07:44 -0600

Hello!

For a school project, I have to detect some colored balls. OpenCV is new for me so, my code is based on the following example:

http://wiki.elphel.com/index.php?title=File:Tennis.tar.gz

The problem is that I cannot detect the yellow balls. This is what the threshold image look like:

image description

This is my code:

    #include <iostream>
#include <opencv\cv.h>
#include <opencv\highgui.h>

using namespace std;
char key;

void cvOpen(const CvArr *src, CvArr *dst, IplConvKernel *element)
{
    cvErode (src, dst, element, 1);
    cvDilate(src, dst, element, 1);
}

void cvClose(const CvArr *src, CvArr *dst, IplConvKernel *element)
{
    cvDilate(src, dst, element, 1);
    cvErode (src, dst, element, 1);
}


IplImage *detectBalls (IplImage **_src)
{
    IplImage *src = *_src;
    CvSize size = cvGetSize(src);
    IplImage *hsv = cvCreateImage(size, IPL_DEPTH_8U, 3);
    cvCvtColor(src, hsv, CV_BGR2HSV);  

    CvMat *mask = cvCreateMat(size.height, size.width, CV_8UC1);
    cvInRangeS(hsv, cvScalar(14, 135, 139, 0),
                    cvScalar(30, 1.00*256, 1.00*256, 0), mask);
    cvReleaseImage(&hsv);

    IplConvKernel *se21 = cvCreateStructuringElementEx(21, 21, 10, 10, CV_SHAPE_RECT, NULL);
    IplConvKernel *se11 = cvCreateStructuringElementEx(11, 11, 5,  5,  CV_SHAPE_RECT, NULL);
    cvClose(mask, mask, se21); // See completed example for cvClose definition
    cvOpen(mask, mask, se11);  // See completed example for cvOpen  definition
    cvReleaseStructuringElement(&se21);
    cvReleaseStructuringElement(&se11);

    /* Copy mask into a grayscale image */
    IplImage *hough_in = cvCreateImage(size, 8, 1);
    cvCopy(mask, hough_in, NULL);
    cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0);

    /* Run the Hough function */
    CvMemStorage *storage = cvCreateMemStorage(0);
    CvSeq *circles = cvHoughCircles(hough_in, storage,
        CV_HOUGH_GRADIENT, 4, size.height/10, 100, 40, 0, 0);
    cvReleaseMemStorage(&storage);

    int i;
    for (i = 0; i < circles->total; i++) {
             float *p = (float*)cvGetSeqElem(circles, i);
         CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1]));
         CvScalar val = cvGet2D(mask, center.y, center.x);
         if (val.val[0] < 1) continue;
             cvCircle(src,  center, 3,             CV_RGB(0,255,0), -1, CV_AA, 0);
             cvCircle(src,  center, cvRound(p[2]), CV_RGB(255,0,0),  3, CV_AA, 0);
             cvCircle(mask, center, 3,             CV_RGB(0,255,0), -1, CV_AA, 0);
             cvCircle(mask, center, cvRound(p[2]), CV_RGB(255,0,0),  3, CV_AA, 0);
    }

        cout << "Number of circles: ";
        cout << circles->total;
        cout << "\n";   



    return hough_in;
}

int main()
{
    cvNamedWindow("out", 0);
    cvNamedWindow("img", 0);
    CvCapture* capture = cvCaptureFromCAM(1);  //Capture using any camera connected to your system
    while(1){ //Create infinte loop for live streaming

        IplImage *frame = cvQueryFrame(capture); //Create image frames from capture
        IplImage *frameOut = detectBalls(&frame);
        cvShowImage("img", frame);   //Show image frames on created window
        cvShowImage ("out", frameOut);
        key = cvWaitKey(10);     //Capture Keyboard stroke
        if (char(key) == 27){
            break;      //If you hit ESC key loop will break.
        }
    }
    cvReleaseCapture(&capture); //Release capture.
    cvDestroyWindow("img"); //Destroy Window
    cvDestroyWindow("out");
    return 0;
}

Can someone help me ?

Kind regards,

Zahir M

edit retag flag offensive close merge delete

Comments

2

Oh, come on... still using C functions?? I am pretty sure that that may be the problem... Or something else, but please pass to C++

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-10-30 11:44:34 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2014-10-30 13:42:09 -0600

It's very strange because your binary image is very good! Try with the two last parameters:

CvSeq *circles = cvHoughCircles(hough_in, storage,
    CV_HOUGH_GRADIENT, 4, size.height/10, 100, 40, 1, size.height);

If it's not working, try to analyse storage value (I don't use C version, so I'm not sure what the function returns). But as suggested by thdrksdfthmn, use the C++ version of opencv ;-) Look for this exemple in c++, it's easier and well tested!

edit flag offensive delete link more

Question Tools

Stats

Asked: 2014-10-30 10:49:28 -0600

Seen: 2,567 times

Last updated: Oct 30 '14