1

Im using OpenCV to help me detect a coin in an image taken from an iPhone camera. Im using HoughCircles method to help me find them but the results are less than hopeful.

cv::Mat greyMat;
    cv::Mat filteredMat;
    cv::vector<cv::Vec3f> circles;
    cv::cvtColor(mainImageCV, greyMat, CV_BGR2GRAY);

    cv::threshold(greyMat, filteredMat, 100, 255, CV_THRESH_BINARY);

    for ( int i = 1; i < 31; i = i + 2 )
    {
//        cv::blur( filteredMat, greyMat, cv::Size( i, i ), cv::Point(-1,-1) );
        cv::GaussianBlur(filteredMat, greyMat, cv::Size(i,i), 0);
//        cv::medianBlur(filteredMat, greyMat, i);
//        cv::bilateralFilter(filteredMat, greyMat, i, i*2, i/2);
    }

    cv::HoughCircles(greyMat, circles, CV_HOUGH_GRADIENT, 1, 50);

    NSLog(@"Circles: %ld", circles.size());

    for(size_t i = 0; i < circles.size(); i++)
    {
        cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
        int radius = cvRound(circles[i][2]);
        cv::circle(greyMat, center, 3, cv::Scalar(0,255,0));
        cv::circle(greyMat, center, radius, cv::Scalar(0,0,255));
    }

    [self removeOverViews];
    [self.imageView setImage: [self UIImageFromCVMat:greyMat]];

This current segment of code returns that i have 15 circles and the are all position along the right side of the image which has me confused.

image with the "circles" drawn over

Im new to OpenCV and there are barely any examples for iOS which has left me desperate.

Any help would be greatly appreciated, thanks in advance!

G_Money
  • 318
  • 7
  • 22
  • 1
    The small amount of work that I have worked with hough circles is that hough circles work best on binary image, i.e., a image with white pixels showing the edge points with whom the circle is to be made and black out everything else. In your image, you are not passing a binary image. Every pixel work as edge point and hence anywhere a circle can be made. – t0mkaka May 24 '13 at 08:40
  • 1
    The main point is that you need to remove noise from the image. Try to blur it. – t0mkaka May 24 '13 at 08:42
  • Ok, but which type of blurring should i use? Normalized box filter, Gaussian filter, Median filter or Bilateral filter? Which would be most effective for what i want to do? – G_Money May 24 '13 at 15:27
  • And should i remove the noise before i grey it out? or after? – G_Money May 24 '13 at 15:37

3 Answers3

2

Your algorithm doesn't make much sense. It seems that you are using cv::GaussianBlur iteratively, but when you run HoughCircles on it, it's only going to work on the grey image that has been filtered by a GassianBlur with a 31x31 kernel, which is going to blur the crap out of the image. It might make better sense to do something like this to see the best results:

This will show you all images iteratively, which I believe is what you wanted to do in the first place.

// NOTE only psuedocode, won't compile, need to fix up.
for ( int i = 1; i < 31; i = i + 2 )
{
    cv::GaussianBlur(filteredMat, greyMat, cv::Size(i,i), 0);
    cv::HoughCircles(greyMat, circles, CV_HOUGH_GRADIENT, 1, 50);

    for(size_t i = 0; i < circles.size(); i++)
    {
        cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
        int radius = cvRound(circles[i][2]);
        cv::circle(greyMat, center, 3, cv::Scalar(0,255,0));
        cv::circle(greyMat, center, radius, cv::Scalar(0,0,255));
    }
    cv::imshow("Circles i " + i, greyMat);
}

You still need some edges for the HoughCircle implementation to work. It uses a Canny edge detector and if you are blurring your image that much.

Also I would suggest you work with the bilateralFilter which blurs but attempts to keep some edges.

This might help as well for defining the correct parameters: HoughCircles Parameters to recognise balls

Community
  • 1
  • 1
jluzwick
  • 2,005
  • 1
  • 15
  • 23
0

All the above code does is run the same process over and over, so your circles detect the drawn circles over and over again. Not the best. Also uses Gaussian Blur over and over, not the best way, in my opinion. I can see the Gaussian Blur in a for loop to make the image more readable, but not HoughCircles in the for loop. You need to include all the variables in houghcircles, it doubled my recognition rate when I used them all.

cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, 30, 50, 20, 10, 25);

Same format that is available on opencv website it is the C++ format.

Here is a link to my iPhone sim pic. Costco aspirin on my desktop. App counts circles in image and displays total in label.

enter image description here

Here is my code, it has a lot of comments included to show what I have tried...and sifted through. Hope this helps. OpenCV install in xcode

Community
  • 1
  • 1
0

I know this is an old question, so just putting this here in case someone else will make the same mistake (as did I...):

This line:

cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));

has the brackets messed up, the double "((" at the beginning is causing the point to be initialized with only one parameter instead of two, it should be:

cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));

Hope that helps.

Kamil Solecki
  • 1,106
  • 20
  • 34
O.z
  • 1
  • 1