OpenCV cvFindContours – comment séparer les composants d’un contour

Je me suis amusé avec OpenCV et, avec beaucoup d’essais et d’erreurs, j’ai appris à détecter les cercles (pièces de monnaie) sur une photo. Tout fonctionne très bien, sauf lorsque je place des pièces directement les unes à côté des autres (comme indiqué ci-dessous, ignorez le fait que la deuxième image est à l’envers).

Photo originaleContours trouvés

Il semble que cvFindContours pense que c’est le même object. Ma question est la suivante: comment puis-je séparer ces contours en leurs objects distincts ou obtenir une liste des contours déjà séparés?

Les parameters que j’ai utilisés pour cvFindContours sont:

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

Toute aide ou conseil serait grandement apprécié.

Ce n’est pas génial, mais cela montre comment s’y rendre:

 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: %dy: %dr: %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); 

entrez la description de l'image ici

Vous pouvez essayer de seuiller ( cvThreshold ) l’image, puis d’éroder ( cvErode ) l’image binary résultante pour séparer les pièces. Trouvez ensuite les contours de l’image érodée.