图像的膨胀 (Dilation) 和腐蚀 (Erosion) 是两种基本的形态学运算, 主要用来寻找图像中的极大区域和极小区域. 其中膨胀类似于 "领域扩张", 将图像中的高亮区域或白色部分进行扩张, 其运行结果图比原图的高亮区域更大; 腐蚀类似于 "领域被蚕食", 将图像中的高亮区域或白色部分进行缩减细化, 其运行结果图比原图的高亮区域更小.
1. 图像膨胀
膨胀的运算符是 "⊕", 其定义如下:
该公式表示用 B 来对图像 A 进行膨胀处理, 其中 B 是一个卷积模板或卷积核, 其形状可以为正方形或圆形, 通过模板 B 与图像 A 进行卷积计算, 扫描图像中的每一个像素点, 用模板元素与二值图像元素做 "与" 运算, 如果都为 0, 那么目标像素点为 0, 否则为 1. 从而计算 B 覆盖区域的像素点最大值, 并用该值替换参考点的像素值实现膨胀. 下图是将左边的原始图像 A 膨胀处理为右边的效果图 A⊕B.
2. 图像腐蚀
腐蚀的运算符是 "-", 其定义如下:
该公式表示图像 A 用卷积模板 B 来进行腐蚀处理, 通过模板 B 与图像 A 进行卷积计算, 得出 B 覆盖区域的像素点最小值, 并用这个最小值来替代参考点的像素值. 如图所示, 将左边的原始图像 A 腐蚀处理为右边的效果图 A-B.
处理结果如下图所示:
äº. 图像腐蚀代码实现
1. 基础理论
形态学转换主要针对的是二值图像(0 或 1). 图像腐蚀类似于 "领域被蚕食", 将图像中的高亮区域或白色部分进行缩减细化, 其运行结果图比原图的高亮区域更小. 其主要包括两个输入对象:
(1)二值图像
(2)卷积核
卷积核是腐蚀中的关键数组, 采用 numpy 库可以生成. 卷积核的中心点逐个像素扫描原始图像, 如下图所示:
被扫描到的原始图像中的像素点, 只有当卷积核对应的元素值均为 1 时, 其值才为 1, 否则其值修改为 0. 换句话说, 遍历到的黄色点位置, 其周围全部是白色, 保留白色, 否则变为黑色, 图像腐蚀变小.
2. 函数原型
图像腐蚀主要使用的函数为 erode, 其原型如下:
dst = cv2.erode(src, kernel, iterations)
参数 dst 表示处理的结果, src 表示原图像, kernel 表示卷积核, iterations 表示迭代次数. 下图表示 5*5 的卷积核, 可以采用函数 np.ones((5,5), np.uint8)构建.
注意: 迭代次数默认是 1, 表示进行一次腐蚀, 也可以根据需要进行多次迭代, 进行多次腐蚀.
3. 代码实现
完整代码如下所示:
输出结果如下图所示:
由图可见, 干扰的细线被进行了清洗, 但仍然有些轮廓, 此时可设置迭代次数进行腐蚀.
erosion = cv2.erode(src, kernel,iterations=9)
输出结果如下图所示:
三. 图像膨胀代码实现
1. 基础理论
图像膨胀是腐蚀操作的逆操作, 类似于 "领域扩张", 将图像中的高亮区域或白色部分进行扩张, 其运行结果图比原图的高亮区域更大, 线条变粗了, 主要用于去噪.
(1) 图像被腐蚀后, 去除了噪声, 但是会压缩图像.
(2) 对腐蚀过的图像, 进行膨胀处理, 可以去除噪声, 并且保持原有形状.
它也包括两个输入对象:
(1)二值图像或原始图像
(2)卷积核
卷积核是腐蚀中的关键数组, 采用 numpy 库可以生成. 卷积核的中心点逐个像素扫描原始图像, 如下图所示:
被扫描到的原始图像中的像素点, 当卷积核对应的元素值只要有一个为 1 时, 其值就为 1, 否则为 0.
2. 函数原型
图像膨胀主要使用的函数为 dilate, 其原型如下:
dst = cv2.dilate(src, kernel, iterations)
参数 dst 表示处理的结果, src 表示原图像, kernel 表示卷积核, iterations 表示迭代次数. 下图表示 5*5 的卷积核, 可以采用函数 np.ones((5,5), np.uint8)构建.
注意: 迭代次数默认是 1, 表示进行一次膨胀, 也可以根据需要进行多次迭代, 进行多次膨胀. 通常进行 1 次膨胀即可.
3. 代码实现
完整代码如下所示:
输出结果如下所示:
图像去噪通常需要先腐蚀后膨胀, 这又称为开运算, 下篇文章将详细介绍. 如下图所示:
- erosion = cv2.erode(src, kernel)
- result = cv2.dilate(erosion, kernel)
来源: https://yq.aliyun.com/articles/672719