28

I have to code an object detector (in this case, a ball) using OpenCV. The problem is, every single search on google returns me something with FACE DETECTION in it. So i need help on where to start, what to use etc..

Some info:

  • The ball doesn't have a fixed color, it will probably be white, but it might change.
  • I HAVE to use machine learning, doesn't have to be a complex and reliable one, suggestion is KNN (which is WAY simpler and easier).
  • After all my searching, i found that calculating the histogram of samples ball-only images and teaching it to the ML could be useful, but my main concern here is that the ball size can and will change (closer and further from the camera) and i have no idea on what to pass to the ML to classify for me, i mean.. i can't (or can I?) just test every pixel of the image for every possible size (from, lets say, 5x5 to WxH) and hope to find a positive result.
  • There might be a non-uniform background, like people, cloth behind the ball and etc..
  • As I said, i have to use a ML algorithm, that means no Haar or Viola algorithms.
  • Also, I thought on using contours to find circles on a Canny'ed image, just have to find a way to transform a contour into a row of data to teach the KNN.

    So... suggestions?

    Thanks in advance. ;)

karlphillip
  • 87,606
  • 33
  • 227
  • 395
hfingler
  • 1,808
  • 2
  • 28
  • 34

1 Answers1

37

Well, basically you need to detect circles. Have you seen cvHoughCircles()? Are you allowed to use it?

This page has good info on how detecting stuff with OpenCV. You might be more interested on section 2.5.

This is a small demo I just wrote to detect coins in this picture. Hopefully you can use some part of the code to your advantage.

Input: input img

Outputs: output opencv img

// compiled with: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv`
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char** argv)
{
    IplImage* img = NULL;

    if ((img = cvLoadImage(argv[1]))== 0)
    {
        printf("cvLoadImage failed\n");
    }

    IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    CvMemStorage* storage = cvCreateMemStorage(0);

    cvCvtColor(img, gray, CV_BGR2GRAY);

    // This is done so as to prevent a lot of false circles from being detected
    cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7);

    IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
    IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
    cvCanny(gray, canny, 50, 100, 3);

    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, gray->height/3, 250, 100);
    cvCvtColor(canny, rgbcanny, CV_GRAY2BGR);

    for (size_t i = 0; i < circles->total; i++)
    {
         // round the floats to an int
         float* p = (float*)cvGetSeqElem(circles, i);
         cv::Point center(cvRound(p[0]), cvRound(p[1]));
         int radius = cvRound(p[2]);

         // draw the circle center
         cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0 );

         // draw the circle outline
         cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0 );

         printf("x: %d y: %d r: %d\n",center.x,center.y, radius);
    }


    cvNamedWindow("circles", 1);
    cvShowImage("circles", rgbcanny);

    cvSaveImage("out.png", rgbcanny);
    cvWaitKey(0);

    return 0;
}

The detection of the circles depend a lot on the parameters of cvHoughCircles(). Note that in this demo I used Canny as well.

karlphillip
  • 87,606
  • 33
  • 227
  • 395
  • I'll check if i can use it... if it's a yes, i could get histograms of circle-only images, then when i want to find circles in an image, turn to grey, use this function to get a bounding-box and classify it with the KNN (pretty stupid, right?). Thanks btw. – hfingler Jun 20 '11 at 20:16
  • Wow you are fast :P I'll probably end up doing what I said on the earlier comment because he REALLY wants ML. And since im in love with python, short code incoming! I'll post the final code here, to help whoever needs something like this. Thanks a lot for that example code, just gotta learn the parameters now. – hfingler Jun 20 '11 at 20:31
  • 1
    I am maybe wrong but it seems that the call to the canny function is useless since the cvHoughCircles function is called with the "gray" IplImage and not the "canny" IplImage... – Kéza Mar 16 '13 at 17:25
  • 4
    Your links are either dead or just having issues right now--FYI. – MuffinTheMan Apr 03 '13 at 15:27
  • Thanks for pointing that out, but there's nothing I can do about it since those pages aren't mine. Hopefully they will come back. – karlphillip Apr 03 '13 at 16:36
  • the CVHoughCircles function already includes a canny filter. its not mentioned in the docs, but the cookbook mentions this 'between the lines'... –  Feb 18 '13 at 23:21
  • The broken link to that wiki page can be found through the wayback machine: http://web.archive.org/web/20130504190215/http://cgi.cse.unsw.edu.au/~cs4411/wiki/index.php?title=OpenCV_Guide#Detecting_circles In case that new link doesn't hold either, I recopied and reformatted the relevant section from that wiki page on: http://stackoverflow.com/a/21472252/320111 – Stephan Branczyk Jan 31 '14 at 07:14
  • Showing a sample with coins overlapped would show some power of the Hough transform. Although you can see some perspective issue due to use of a disk as opposed to the OPs spheres... Just to complement an excellent post. – artless noise Dec 26 '20 at 15:38