OpenCV中的Blob提取

13
我正在使用OpenCV对一幅图片进行颜色过滤,因此我得到了一个检测区域的二进制图像。
现在我想要侵蚀这些区域,然后摆脱较小的部分,并找出最大“斑块”的x、y坐标。
我正在寻找哪个库是最好使用的建议?我看到了cvBlob和cvBlobsLib,但我不太确定如何设置它们。我是要将它们与项目一起编译,还是要将它们编译并安装到系统中(就像我使用OpenCV那样)?
我目前在Ubuntu上使用Code::Blocks IDE(虽然这不应该限制事情)。
4个回答

11

2
干得好,Jason。我已经集成了你的补丁,看起来运行良好。速度也很快。也许添加一些属性函数会更好(如面积、重心等)。无论如何,感谢你的出色工作。我希望OpenCV团队能尽快集成你的补丁。在我看来,这是OpenCV的一个严重缺陷,特别是因为其他库已经过时,只使用IplImage*... - Jean-Philippe Jodoin
现在API中有这个吗?如果有的话,提供文档链接将有助于未来的读者。 - dashesy

11
您可以使用findContours来实现,详见OpenCV手册和一篇查找连接组件的教程

编辑:来自教程的代码(通过Archive.org)

#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int main(int argc, char *argv[])
{
    IplImage *img, *cc_color; /*IplImage is an image in OpenCV*/
    CvMemStorage *mem;
    CvSeq *contours, *ptr;
    img = cvLoadImage(argv[1], 0); /* loads the image from the command line */
    cc_color = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);

    cvThreshold(img, img, 150, 255, CV_THRESH_BINARY);
    mem = cvCreateMemStorage(0);
    cvFindContours(img, mem, &contours, sizeof(CvContour), CV_RETR_CCOMP,
        CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));


    for (ptr = contours; ptr != NULL; ptr = ptr->h_next) {
        CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
        cvDrawContours(cc_color, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
    }

    cvSaveImage("result.png", cc_color);
    cvReleaseImage(&img);
    cvReleaseImage(&cc_color);
    return 0;
}

这看起来也很有前途,只是想知道如何找到最大的轮廓/斑点 - 谢谢 :) - amr
我认为你可以计算轮廓的面积。有一些函数可以实现这个功能。 - Utkarsh Sinha
是的,我刚刚计算了轮廓边界框的面积,就完成了任务。 - amr
1
第二个链接已经失效,第一个链接似乎也没有响应,请您更新一下。 - dashesy
第二个链接在Archive.org上仍然有效 - 回答可能需要更新 https://web.archive.org/web/20110505194913/http://www.associatedcontent.com/article/2695649/connected_components_using_opencv.html - Fuhrmanator

10

很遗憾,OpenCV没有任何连通组件标记功能,这似乎是计算机视觉库的一个严重缺陷。不过,最近我有类似的需求,所以我自己实现了CCL例程 - 在CCL维基百科页面上描述了几种不同的算法,并且它们都相当简单易懂。


1
这似乎是最好的选择,谢谢 :) 你说得对,这似乎是OpenCV的一个巨大疏忽。 - amr
在OpenCV网站上有一个第三方的blob库(cvBlobsLib或类似的),但我看了一下,代码质量不是很好。在这种情况下最好自己编写代码。 - Paul R
如另一个答案中所提到的,findContours函数是否提供了等效于连通组件标记的功能? - carnieri
@carnieri:这取决于您要收集的信息类型 - cvFindContours将多边形拟合到斑点上,您可以从这些多边形中获取某些信息,但在我的情况下,我需要知道每个斑点中连接像素的数量,而cvFindContours似乎无法实现这一点。然而,使用常规CCL算法非常简单(只需对标签值进行直方图处理)。 - Paul R
很好知道 - 如果@amr还在的话,最好他现在将你的答案标记为已接受,而不是我的过时答案。 - Paul R

0

我认为在使用OpenCV处理二进制大对象时,最好且最简单的选择是使用cvBlob库。它是OpenCV的补充库,非常易于使用。


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