问题描述
我一直在使用 OpenCV,并且通过大量的试验和错误成功地学习了如何检测照片中的圆圈(硬币).一切都很好,除了我将硬币直接放在彼此旁边(如下所示,忽略第二张图片倒置的事实).
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).
似乎是因为硬币靠得很近,cvFindContours 认为它们是同一个物体.我的问题是如何将这些轮廓分成单独的对象,或者获取已经分离的轮廓列表.
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.
我用于 cvFindContours 的参数是:
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.
推荐答案
这不是很好,但它显示了如何到达那里:
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);
这篇关于OpenCV cvFindContours - 如何分离轮廓的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!