By Grinneh


2011-05-18 11:44:01 8 Comments

I've been playing around with OpenCV and with alot of trial and error have managed to learn how to detect circles (coins) in a photo. Everything is working great, except when I place coins directly next to each other (as seen below, ignore the fact that the 2nd image is upside down).

Original Photo Contours Found

It seems because the coins are so close together cvFindContours think they are the same object. My question is how can I separate these contours into their separate objects, or get a list of contours that are already separated.

The parameters I used for cvFindContours are:

cvFindContours( img, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0) );

Any help or advice would be greatly appreciated.

2 comments

@karlphillip 2011-08-03 18:11:40

This is not great, but it shows how to get there:

IplImage* src = cvLoadImage(argv[1], CV_LOAD_IMAGE_UNCHANGED);
IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 
cvCvtColor(src, gray, CV_BGR2GRAY);
cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7); 

IplImage* cc_img = cvCreateImage(cvGetSize(gray), gray->depth, 3); 
cvSetZero(cc_img);
CvScalar(ext_color);

cvCanny(gray, gray, 10, 30, 3); 

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, src->height/6, 100, 50);
cvCvtColor(gray, src, 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(cc_img, center, 3, CV_RGB(0,255,0), -1, 8, 0 );

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

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

CvMemStorage *mem;
mem = cvCreateMemStorage(0);
CvSeq *contours = 0;
cvCvtColor(cc_img, gray, CV_BGR2GRAY);
// Use either this:
int n = cvFindContours(gray, mem, &contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
// Or this:
//int n = cvFindContours(gray, mem, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

for (; contours != 0; contours = contours->h_next)
{
    ext_color = CV_RGB( rand()&255, rand()&255, rand()&255 ); //randomly coloring different contours
    cvDrawContours(cc_img, contours, ext_color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
}

cvSaveImage("out.png", cc_img);

enter image description here

@Grinneh 2011-08-04 05:12:55

Thanks for your reply, what I failed to mention in the first post is that preserving the size of each coin was important, as the project was meant to determine what value each coin was based on its size. I'll see if I can tweak it somehow for accuracy. Thanks again

@Karl Voigtland 2011-05-18 11:55:58

You could try thresholding (cvThreshold) the image and then erode (cvErode) the resulting binary image to separate the coins. Then find the contours of the eroded image.

@Grinneh 2011-05-18 21:07:56

Thanks for the suggestion, but I found to erode the image to the point where I could separate the contours resulted in the coins not looking like circles anymore. Losing a little bit of circle accuracy is ok, but overall I want to preserve it as much as possible

@Valentin Heinitz 2012-05-29 12:18:11

Yes, this way is also suggested in OpenCV book for separating cells on a microscope image .

Related Questions

Sponsored Content

7 Answered Questions

[SOLVED] How to sharpen an image in OpenCV?

11 Answered Questions

[SOLVED] How do function pointers in C work?

  • 2009-05-08 15:49:17
  • Yuval Adam
  • 747770 View
  • 1115 Score
  • 11 Answer
  • Tags:   c function-pointers

26 Answered Questions

[SOLVED] How do you set, clear, and toggle a single bit?

10 Answered Questions

[SOLVED] How to detect a Christmas Tree?

10 Answered Questions

5 Answered Questions

[SOLVED] How do I find Waldo with Mathematica?

1 Answered Questions

How to detect an image between shapes from camera

2 Answered Questions

[SOLVED] OpenCV cvFindContours finds only one contour

2 Answered Questions

[SOLVED] cvFindContours() not detecting separate components

1 Answered Questions

Sponsored Content