【youcans 的 OpenCV 例程200篇】136. 灰度腐蚀和灰度膨胀
5. 灰度级形态学
灰度级形态学将形态学操作从二值图像扩展到灰度图像。灰度形态学处理也有腐蚀、膨胀、开运算、闭运算、顶帽操作、低帽操作等操作,可以实现图像平滑、图像增强、图像分割功能。
把图像像素点的灰度值视为高度,不同的灰度级表示不同的高度,整个图像就像一张高低起伏的地形图。明亮的区域(灰度值大)相当于高山,黑暗的区域(灰度值小)相当于深谷,边缘区域即明亮与黑暗的交界相当于悬崖。
灰度级形态学中的结构元的基本功能与二值形态学中的结构元类似,都是检查图像中的特定结构特征的”探测器“。灰度级形态学中的结构元分为平坦结构元和非平坦结构元,这两类结构元具有不同的灰度剖面。
5.1 灰度腐蚀和灰度膨胀
腐蚀腐蚀使图像中白色高亮部分被腐蚀,“邻域被蚕食”;膨胀使图像中的白色高亮部分进行膨胀,“邻域扩张”。
灰度腐蚀是由结构元确定的邻域中选取图像值与结构元值之差的最小值,灰度膨胀是由结构元素确定的邻域中选取图像值与结构元值之和的最大值。
平坦结构元的高度为零,对灰度图像的腐蚀或膨胀运算,简化为对每个像素在结构元邻域内求图像灰度级的最小值或最大值。
令 f ( x , y ) f(x,y) f(x,y) 是一幅灰度图像, b ( x , y ) b(x,y) b(x,y) 是一个平坦结构元。
当结构元 b 的原点是 (x,y)时,b 对图像 f 在位置 (x,y) 的灰度腐蚀定义为图像 f 与 b 重合区域中的最小值:
[
f
⊖
b
]
(
x
,
y
)
=
min
(
s
,
t
)
∈
b
{
f
(
x
+
s
,
y
+
t
)
}
[f \ominus b](x,y) = \min_{(s,t) \in b} \{ f(x+s,y+t) \}
[f⊖b](x,y)=(s,t)∈bmin{f(x+s,y+t)}
对灰度图像进行腐蚀运算,在邻域内求灰度级的最小值,腐蚀后的图像比原图像暗,在比结构元小的区域中的亮特征减少,暗特征变大。
类似地,当结构元 b 对图像 f 在位置 (x,y) 的灰度膨胀定义为图像 f 与
b
^
\hat{b}
b^ 重合区域中的最大值:
[
f
⊕
b
]
(
x
,
y
)
=
max
(
s
,
t
)
∈
b
^
{
f
(
x
−
s
,
y
−
t
)
}
[f \oplus b](x,y) = \max_{(s,t) \in \hat{b}} \{ f(x-s,y-t) \}
[f⊕b](x,y)=(s,t)∈b^max{f(x−s,y−t)}
对灰度图像进行膨胀运算,在邻域内求灰度级的最大值,膨胀后的图像比原图像亮,在比结构元小的区域中的暗特征减少,亮特征变大。
OpenCV 提供了函数 cv.erode 可以实现图像的灰度腐蚀:
cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
OpenCV 提供了函数 cv.dilate 可以实现图像的灰度膨胀:
cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
而函数 cv.getStructuringElement 可以构造不同形状和尺寸的结构元。
函数说明:
cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
cv.getStructuringElement(shape, ksize[, anchor] ) -> retval
参数说明:
- shape:结构元素形状的类型
- cv.MORPH_RECT:矩形,全 1 矩阵
- cv.MORPH_CROSS:交叉型, 十字交叉为 1,其它为 0
- cv.MORPH_ELLIPSE: 椭圆型,椭圆内为 1,其它为 0
- ksize:内核的尺寸
- anchor:卷积核的锚点位置,可选项,默认值 (-1, -1) 表示锚点为中心点
- retval:返回指定形状和尺寸的结构元素
例程 10.26:灰度级形态学之灰度腐蚀
# 10.26: 灰度级形态学之灰度腐蚀
imgGray = cv2.imread("../images/Fig0937a.tif", flags=0) # flags=0 灰度图像
# 图像腐蚀
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
imgErode1 = cv2.erode(imgGray, kernel=element) # 图像腐蚀
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5))
imgErode2 = cv2.erode(imgGray, kernel=element) # 图像腐蚀
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (9,9))
imgErode3 = cv2.erode(imgGray, kernel=element) # 图像腐蚀
plt.figure(figsize=(10, 5))
plt.subplot(141), plt.axis('off'), plt.title("Origin")
plt.imshow(imgGray, cmap='gray', vmin=0, vmax=255)
plt.subplot(142), plt.title("eroded kSize=(3,3)"), plt.axis('off')
plt.imshow(imgErode1, cmap='gray', vmin=0, vmax=255)
plt.subplot(143), plt.title("eroded kSize=(9,9)"), plt.axis('off')
plt.imshow(imgErode2, cmap='gray', vmin=0, vmax=255)
plt.subplot(144), plt.title("eroded kSize=(25,25)"), plt.axis('off')
plt.imshow(imgErode3, cmap='gray', vmin=0, vmax=255)
plt.tight_layout()
plt.show()
例程 10.27:灰度级形态学之灰度膨胀
# 10.27: 灰度级形态学之灰度膨胀
imgGray = cv2.imread("../images/Fig0937a.tif", flags=0) # flags=0 灰度图像
# 灰度腐蚀
element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
imgDilate1 = cv2.dilate(imgGray, kernel=element) # 图像膨胀
element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
imgDilate2 = cv2.dilate(imgGray, kernel=element) # 图像膨胀
plt.figure(figsize=(9, 6))
plt.subplot(131), plt.axis('off'), plt.title("Origin")
plt.imshow(imgGray, cmap='gray', vmin=0, vmax=255)
plt.subplot(132), plt.title("Dilate kSize=(3,3)"), plt.axis('off')
plt.imshow(imgDilate1, cmap='gray', vmin=0, vmax=255)
plt.subplot(133), plt.title("Dilate kSize=(5,5)"), plt.axis('off')
plt.imshow(imgDilate2, cmap='gray', vmin=0, vmax=255)
plt.tight_layout()
plt.show()
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/123565619)
Copyright 2022 youcans, XUPT
Crated:2022-3-24