Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
572 views
in Technique[技术] by (71.8m points)

c - OpenCV cvFindContours - how do I separate components of a contour

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
", 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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...