Contours opencv:如何消除二进制图像中的小轮廓

Man*_*j M 7 c c++ opencv image-processing visual-c++

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

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

我获得的二进制图像:

在此输入图像描述

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

在此输入图像描述

kar*_*lip 10

好的,我相信您的问题可以通过OpenCV最近推出的边界框演示来解决.

在此输入图像描述

您可能已经注意到,您感兴趣的对象应位于图片中最大的矩形绘制内.幸运的是,这段代码并不是很复杂,我相信你可以通过调查和试验来解决这个问题.


Mas*_*hou 7

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

通常你会得到这样的轮廓

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));
Run Code Online (Sandbox Code Playgroud)

使用Canny()预处理,您将获得轮廓线段,但每个线段都以边界像素存储为闭环.在这种情况下,您可以检查长度并删除小的长度

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

如果没有Canny()预处理,您将获得对象的轮廓.相似性,您也可以使用区域来定义阈值以消除小对象,如OpenCV教程所示

vector<Point> contour = contours[i];
double area0 = contourArea(contour);
Run Code Online (Sandbox Code Playgroud)

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


小智 1

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

另外,正如 sue-ling 提到的,同时使用侵蚀和扩张来近似保留面积是一个好主意。要去除小噪声位,请先使用侵蚀,要填充孔,请先使用膨胀。

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