Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV cvFindContours-如何分离轮廓的组件_C_Opencv_Image Processing_Geometry_Object Detection - Fatal编程技术网

OpenCV cvFindContours-如何分离轮廓的组件

OpenCV cvFindContours-如何分离轮廓的组件,c,opencv,image-processing,geometry,object-detection,C,Opencv,Image Processing,Geometry,Object Detection,我一直在玩OpenCV,通过大量的尝试和错误,我终于学会了如何检测照片中的圆圈(硬币)。一切都很好,除了我把硬币直接放在彼此旁边(如下图所示,忽略第二张图片是颠倒的这一事实) 这似乎是因为这些硬币靠得太近了,所以被发现的恐龙认为它们是同一个物体。我的问题是如何将这些轮廓分割成单独的对象,或者如何获得已分割轮廓的列表 我用于cvFindContours的参数有: cvFindContours( img, storage, &contour, sizeof(CvContour), CV_

我一直在玩OpenCV,通过大量的尝试和错误,我终于学会了如何检测照片中的圆圈(硬币)。一切都很好,除了我把硬币直接放在彼此旁边(如下图所示,忽略第二张图片是颠倒的这一事实)

这似乎是因为这些硬币靠得太近了,所以被发现的恐龙认为它们是同一个物体。我的问题是如何将这些轮廓分割成单独的对象,或者如何获得已分割轮廓的列表

我用于cvFindContours的参数有:

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

如果您能提供任何帮助或建议,我们将不胜感激。

您可以尝试对图像进行阈值分割(),然后腐蚀()生成的二值图像以分离硬币。然后找到被侵蚀图像的轮廓。

这不是很好,但它显示了如何到达那里:

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);
IplImage*src=cvLoadImage(argv[1],CV\u LOAD\u IMAGE\u未更改);
IplImage*gray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
CVT颜色(src、灰色、CV_bgr2灰色);
cvSmooth(灰色、灰色、CV_高斯、7、7);
IplImage*cc_img=cvCreateImage(cvGetSize(灰色),灰色->深度,3);
cvSetZero(cc_img);
CvScalar(外部颜色);
cvCanny(灰色、灰色、10、30、3);
CvMemStorage*storage=cvCreateMemStorage(0);
CvSeq*circles=cvHoughCircles(灰色、存储、CV_HOUGH_渐变、1、src->高度/6100、50);
CVT颜色(灰色、src、CV_灰色2BGR);
对于(大小i=0;itotal;i++)
{   
//将浮点数四舍五入为整数
float*p=(float*)cvGetSeqElem(圆,i);
cv::点中心(cvRound(p[0]),cvRound(p[1]);
int radius=cvRound(p[2]);
//画圆心
//CV圆(cc_img,center,3,CV_RGB(0255,0),-1,8,0);
//画圆的轮廓
CV圆(cc_img,中心,半径+1,CV_RGB(0,0255),2,8,0);
//printf(“x:%d y:%d r:%d\n”,中心x,中心y,半径);
}   
CvMemStorage*mem;
mem=cvCreateMemStorage(0);
CvSeq*等高线=0;
CVT颜色(cc_img、灰色、CV_bgr2灰色);
//使用以下任一选项:
int n=cvFindContours(灰色、mem和等高线、尺寸(CvContour)、CV_RETR_CCOMP、CV_CHAIN_近似值、cvPoint(0,0));
//或者这个:
//int n=cvFindContours(灰色、mem和等高线、sizeof(CvContour)、CV_RETR_列表、CV_链约简单、cvPoint(0,0));
对于(;轮廓!=0;轮廓=轮廓->h_下一步)
{
ext_color=CV_RGB(rand()&255,rand()&255,rand()&255);//随机为不同的轮廓着色
cvDrawContours(cc_img,contours,ext_color,CV_RGB(0,0,0),-1,CV_填充,8,cvPoint(0,0));
}
cvSaveImage(“out.png”,cc_img);

从你的“之后”图像中,你可以使用修改后的hough变换()来检测图像中的圆,它应该会给你合理的结果感谢你的建议,但我发现它会侵蚀图像,使轮廓分离,从而使硬币看起来不再像圆。失去一点圆的精确性是可以的,但总的来说,我希望尽可能多地保留它。OpenCV书中也建议使用这种方法在显微镜图像上分离细胞。谢谢你的回复,我在第一篇文章中没有提到的是,保留每枚硬币的大小很重要,因为这个项目的目的是根据硬币的大小来确定每枚硬币的价值。我会看看我是否可以调整它的准确性。再次感谢