Cannot detect yellow balls using OpenCV
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:
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
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++