OpenCV:围绕斑点的轮廓不正确

3
我正在尝试在二进制图像中绘制blob的轮廓,然而有时候,openCV会在两个不同的blob周围绘制一个单一的轮廓。下面是一个例子。我该怎么解决这个问题? alt text 在这个图像中,应该分别为右边的blob和左边的blob绘制两个边界框。我同意它们很接近但是足够远离彼此。我只绘制外部轮廓而不是树或列表。我也使用cvFindNextContour(contourscanner),因为这对我的情况来说更容易实现。
谢谢。

EDIT: Image displayed in the "output" window is from a different function which does just image subtraction. Image displayed in the "contours" window is in the function pplfind(). "output" image is passed to img_con().


IplImage* img_con(IplImage* image){
    int ppl;
    CvMemStorage* memstr = cvCreateMemStorage();
    IplImage* edges = cvCreateImage(cvGetSize(image),8,1);
    cvCanny(image,edges,130,255);
    CvContourScanner cscan = cvStartFindContours(image,memstr,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,cvPoint(0,0));

ppl = pplfind(cscan,cvGetSize(image));
if (ppl !=0 )
    printf("Estimated number of people: %d\n",ppl);
cvEndFindContours(&cscan);
cvClearMemStorage(memstr);

return edges;

int pplfind(CvContourScanner cscan, CvSize frSize){ ofstream file; char buff[50]; file.open("box.txt",ofstream::app); int ppl =0; CvSeq* c; IplImage *out = cvCreateImage(frSize,8,3); while (c = cvFindNextContour(cscan)){ CvRect box = cvBoundingRect(c,1); if ((box.height > int(box.width*1.2))&&(box.height>20)){//&&(box.width<20)){// ppl++; cvRectangle(out,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),CV_RGB(255,0,50),1);

        cvShowImage("contours",out);
        //cvWaitKey();
    }
    //printf("Box Height: %d , Box Width: %d ,People: %d\n",box.height,box.width,ppl);
    //cvWaitKey(0);
    int coord = sprintf_s(buff,"%d,%d,%d\n",box.width,box.height,ppl);
    file.write(buff,coord);
}
file.close();
cvReleaseImage(&out);
return ppl;

}


1
你可能应该展示你的代码... - etarion
抱歉耽搁了发布代码的时间。 - AtharvaI
carnieri的回答是我问题的正确解决方案,但我不明白为什么使用cvFindNextContour不起作用。如果有人知道,请告诉我。 - AtharvaI
1个回答

3

我从未使用过cvFindNextContour,但在图像上运行带有CV_RETR_EXTERNALcvFindContours似乎很好用:

alt text

我使用OpenCV + Python,所以这段代码可能对你没有用,但为了完整起见,在这里提供一下:

contours = cv.findContours(img, cv.CreateMemStorage(0), mode=cv.CV_RETR_EXTERNAL)
while contours:
    (x,y,w,h) = cv.BoundingRect(contours)
    cv.Rectangle(colorImg, (x,y), (x+w,y+h), cv.Scalar(0,255,255,255))
    contours = contours.h_next()

编辑:您问如何仅绘制具有特定属性的轮廓;这将是类似于以下内容:

contours = cv.findContours(img, cv.CreateMemStorage(0), mode=cv.CV_RETR_EXTERNAL)
while contours:
    (x,y,w,h) = cv.BoundingRect(contours)
    if h > w*1.2 and h > 20:
        cv.Rectangle(colorImg, (x,y), (x+w,y+h), cv.Scalar(0,255,255,255))
    contours = contours.h_next()

嗨,它正常工作了。我如何检查每个边界框?我只想为符合某种尺寸标准的轮廓绘制这些框。我看到所有轮廓都有一个边界框。是否可以从一个帧中迭代遍历每个轮廓?谢谢,我将接受答案,因为它回答了我的主要问题。感谢。 - AtharvaI
1
“while contour”和“contour = contour.h_next()”已经在迭代每个轮廓。我添加了一个示例,仅绘制具有特定属性的轮廓,就像您在代码中所做的那样。 - carnieri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接