【发布时间】:2014-09-18 02:39:07
【问题描述】:
我想平滑二值化图像的轮廓,并认为腐蚀是最好的方法。我知道正常的工作方式是使用 cvDilate(src, dst, 0, iter);其中 0 是一个 3x3 矩阵。
问题是 3x3 矩阵会严重侵蚀我的图像。如何使用 2x2 矩阵或小于默认 3x3 矩阵的任何东西进行侵蚀。
【问题讨论】:
标签: image-processing opencv computer-vision
我想平滑二值化图像的轮廓,并认为腐蚀是最好的方法。我知道正常的工作方式是使用 cvDilate(src, dst, 0, iter);其中 0 是一个 3x3 矩阵。
问题是 3x3 矩阵会严重侵蚀我的图像。如何使用 2x2 矩阵或小于默认 3x3 矩阵的任何东西进行侵蚀。
【问题讨论】:
标签: image-processing opencv computer-vision
如果您的目标是获得具有平滑边缘的二值化图像,那么如果您拥有原始图像,则最好在执行二值化之前使用带有cvSmooth() 的高斯模糊之类的东西。
也就是说,您不仅限于 3x3 内核。 cvDilate() 采用由CreateStructuringElementEx 生成的IplConvKernel,您可以使用该功能制作具有任何(矩形)形状的结构元素。
但是,结构元素相对于必须具有整数坐标的锚点起作用,因此如果使用 2x2 矩阵,则矩阵不能以像素为中心。所以在大多数情况下,最好使用具有奇数行和列的结构元素。
你可以做的是创建一个 3x3 结构元素,其中只有中心值和正上方、下方、左侧和右侧的值是 1,如下所示:
0 1 0
1 1 1
0 1 0
而不是默认:
1 1 1
1 1 1
1 1 1
第一个内核将使边缘稍微平滑一些。
【讨论】:
这是一种快速而肮脏的方法来告诉您膨胀/侵蚀是否适合您:
【讨论】:
使用 C API,您可以使用函数 CreateStructuringElementEx() 创建任何类型和大小的专用 IplConvKernel 对象。如果你使用 C++ API(函数dilate()),用于膨胀的结构元素是你想要的任何矩阵(Mat)。
【讨论】:
全为 1 的内核是低通卷积滤波器。膨胀过滤器将 3X3 区域中的每个像素替换为该 3x3 区域中最暗的像素。侵蚀过滤器将 3x3 区域中的每个像素替换为该 3x3 区域中最亮的像素。也就是说,如果您的背景很亮,而您的前景对象很暗。如果你翻转你的背景和前景,那么你也会翻转你的膨胀和侵蚀过滤器。
此外,如果您想执行“打开”操作,请先执行腐蚀,然后执行膨胀。相反,“关闭”操作是先膨胀后腐蚀。打开往往会删除孤立的像素块,而关闭往往会填补空洞。
【讨论】:
腐蚀和膨胀矩阵应该是奇数顺序
-- 不能使用 2*2 矩阵
卷积矩阵的顺序应该是 1*1 3*3 5*5 7*7 ... 但是奇数
尝试应用 close - Erode 然后扩大图像操作 - 使用 cvMorpologyEx() 函数
【讨论】: