【youcans 的 OpenCV 例程 200 篇】114. 形态学操作之膨胀
形态学的基本思想是利用结构元素测量或提取输入图像中的形状或特征,以便进行图像分析和目标识别。形态学操作都是基于各种形状的结构元,结构元对输入图像进行操作得到输出图像。
腐蚀和膨胀是图像处理中最基本的形态学操作,是很多高级处理方法的基础。腐蚀和膨胀是对白色部分(高亮部分)而言的,膨胀就是图像中的高亮部分进行膨胀,腐蚀就是原图中的高亮部分被腐蚀。
2. 形态学基本操作
2.2 膨胀
膨胀使图像中的白色高亮部分进行膨胀,“邻域扩张”,膨胀效果拥有比原图更大的高亮区域,可以填补图像缺陷,用来扩充边缘或填充小的孔洞,也可以用来连接两个分开的物体。
膨胀的原理是求局部最大值的操作,将 1 值扩充到邻近像素,从而扩大白色值范围、压缩黑色值范围。
结构元 B 对集合 A 的膨胀定义为:
A
⊕
B
=
{
z
∣
(
B
^
)
z
∩
A
≠
∅
}
A \oplus B = \{ z | (\hat B)_z \cap A \neq \varnothing \}
A⊕B={z∣(B^)z∩A=∅}
用卷积来描述膨胀操作,中心为 1、其它为 0 的卷积核沿着图像滑动卷积,与卷积核对应的原图像的像素值中只要有一个为 1, 则图像的中心元素的像素值为 1,否则(全 0)为 0。
用卷积来描述膨胀操作,结构元素 B 是中心为 1、其它为 0 的卷积模板(核):
(1)卷积核 B 沿着图像滑动,扫描图像 A 的每一个像素;
(2)用结构元素与其覆盖的二值图像进行 “与操作”;
(3)如果图像与卷积核对应区域的所有像素值都是 0,则图像的该像素值仍为 0;否则为 1。
在去噪声时通常先进行腐蚀,在去掉白噪声的同时,使前景对象变小;然后再对进行膨胀,此时噪声已经被去除,可以增加前景。
OpenCV 提供了函数 cv.dilate 可以实现图像的膨胀。
函数说明:
cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
函数 cv.dilate 使用指定的结构元(卷积核)膨胀源图像,结构元确定像素邻域的形状,在该邻域上取最大值:
d s t ( x , y ) = max ( x ′ , y ′ ) : e l e m e n t ( x ′ , y ′ ≠ 0 ) s r c ( x + x ′ , y + y ′ ) dst(x,y)= \max_{\enspace (x',y'):element(x',y' \neq 0)} \enspace src(x+x',y+y') dst(x,y)=(x′,y′):element(x′,y′=0)maxsrc(x+x′,y+y′)
参数说明:
- src:输入图像,可以为单通道或多通道,图像深度必须为 CV_8U, CV_16U, CV_16S, CV_32F 或 CV_64F
- dst:输出图像,大小和类型与 src 相同
- kernel:结构元(卷积核),null 时使用 3*3 矩形卷积核
- anchor:卷积核的锚点位置,默认值 (-1, -1) 表示以卷积核的中心为锚点
- iterations:应用膨胀的次数,可选项,默认值为 1
- borderType:边界扩充的类型
- borderValue:当 borderType=BORDER_CONSTANT 时以常量 value 填充扩充边界,默认值为 (0,0,0)
注意事项:
- 函数支持就地模式,腐蚀操作可以迭加使用多次。
- 在多通道图像的情况下,每个通道独立处理 。
例程 10.2:图像的膨胀 (cv.dilate)
# 10.2 图像的膨胀 (cv.dilate)
# cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
# 读取原始图像
imgGray = cv2.imread("../images/handwriting01.png", flags=0) # flags=0 读取为灰度图像
ret, imgBin = cv2.threshold(imgGray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 二值化处理
# 图像膨胀
kSize = (3, 3) # 卷积核的尺寸
kernel = np.ones(kSize, dtype=np.uint8) # 生成盒式卷积核
imgDilate1 = cv2.dilate(imgBin, kernel=kernel) # 图像膨胀
kSize = (5, 5)
kernel = np.ones(kSize, dtype=np.uint8)
imgDilate2 = cv2.dilate(imgBin, kernel=kernel) # 图像膨胀
kSize = (7, 7)
kernel = np.ones(kSize, dtype=np.uint8)
imgDilate3 = cv2.dilate(imgBin, kernel=kernel) # 图像膨胀
plt.figure(figsize=(10, 5))
plt.subplot(141), plt.axis('off'), plt.title("Origin")
plt.imshow(imgBin, cmap='gray', vmin=0, vmax=255)
plt.subplot(142), plt.title("dilate kSize=(3,3)"), plt.axis('off')
plt.imshow(imgDilate1, cmap='gray', vmin=0, vmax=255)
plt.subplot(143), plt.title("dilate kSize=(5,5)"), plt.axis('off')
plt.imshow(imgDilate2, cmap='gray', vmin=0, vmax=255)
plt.subplot(144), plt.title("dilate kSize=(7,7)"), plt.axis('off')
plt.imshow(imgDilate3, cmap='gray', vmin=0, vmax=255)
plt.tight_layout()
plt.show()
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/123251108)
Copyright 2022 youcans, XUPT
Crated:2022-3-2