9

我目前正在从事图像处理项目。我将 Opencv2.3.1 与 VC++ 一起使用。我编写了这样的代码,输入图像被过滤为仅蓝色并转换为二进制图像。二进制图像有一些我不想要的小物体。我想消除那些小物体,所以我使用openCV的cvFindContours()方法来检测二进制图像中的轮廓。但问题是我无法消除图像输出中的小物体。我使用cvContourArea()了function,但没有正常工作..,erode函数也没有正常工作。

所以请有人帮我解决这个问题..

我获得的二进制图像

在此处输入图像描述

我想要获得的结果/输出图像:

在此处输入图像描述

4

6 回答 6

10

好的,相信你的问题可以通过OpenCV最近推出的bounding box demo来解决。

在此处输入图像描述

您可能已经注意到,您感兴趣的对象应该在图片中最大的矩形内。幸运的是,这段代码不是很复杂,我相信你可以通过调查和试验来弄清楚。

于 2012-04-20T02:51:27.967 回答
8

这是我消除小轮廓的解决方案。基本思想是检查每个轮廓的长度/面积,然后从矢量容器中删除较小的轮廓。

通常你会得到这样的轮廓

Mat canny_output; //example from OpenCV Tutorial
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny(src_img, canny_output, thresh, thresh*2, 3);//with or without, explained later.
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

通过 Canny() 预处理,您将获得轮廓段,但是每个段都与边界像素一起存储为闭合环。在这种情况下,您可以检查长度并删除较小的,例如

for (vector<vector<Point> >::iterator it = contours.begin(); it!=contours.end(); )
{
    if (it->size()<contour_length_threshold)
        it=contours.erase(it);
    else
        ++it;
}

如果没有 Canny() 预处理,您将获得对象的轮廓。类似的,你也可以使用面积来定义一个阈值来消除小物体,如 OpenCV 教程所示

vector<Point> contour = contours[i];
double area0 = contourArea(contour);

此 contourArea() 是非零像素的数量

于 2013-08-07T16:16:27.537 回答
1

您确定按小轮廓区域过滤不起作用吗?它一直对我有用。我们可以看看你的代码吗?

此外,正如 sue-ling 所提到的,最好同时使用侵蚀和扩张来近似保留区域。要删除小的嘈杂位,请先使用腐蚀,要填充孔,请先使用扩张。

另外,cv如果您还不知道 * 函数的新 C++ 版本,您可能想查看它们(文档findContours。在我看来,它们更容易使用。

于 2012-04-20T01:31:19.080 回答
0

我相信您可以使用 erode 和 dilate 等形态运算符(在此处阅读更多内容)

您需要使用接近右侧圆半径(您要消除的那个)的内核大小执行腐蚀。然后使用相同的内核进行膨胀以填补侵蚀步骤产生的空白。

仅供参考,腐蚀然后使用相同的内核进行膨胀称为开环。

代码将是这样的

int erosion_size = 30; // adjust with you application
Mat erode_element = getStructuringElement( MORPH_ELLIPSE,
                         Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                         Point( erosion_size, erosion_size ) );
erode( binary_img, binary_img, erode_element );
dilate( binary_img, binary_img, erode_element );
于 2014-06-28T06:31:50.647 回答
0

从前后图像判断,您需要确定所有白色区域或斑点的面积,然后应用阈值面积值。这将消除所有小于该值的区域,只留下第二张图像中看到的大的白色区域。使用 cvFindContours 函数后,尝试使用 0 阶矩。这将返回图像中斑点的区域。此链接可能有助于实现我刚刚描述的内容。 http://www.aishack.in/2010/07/tracking-colored-objects-in-opencv/

于 2012-04-20T01:33:58.047 回答
0

这不是一种快速的方法,但在某些情况下可能很有用。OpencCV 3.0 中有一个新功能——connectedComponentsWithStats。有了它,我们可以获得连接组件的面积并消除不必要的。所以我们可以很容易地去除带孔的圆,与实心圆具有相同的边界框。

于 2015-11-16T13:13:45.210 回答