9.4 Python图像处理之图像数学形态学-基于灰度形态学的应用(形态梯度、形态平滑、高帽变换、低帽变换)
文章目录
1 算法原理
1.1 形态学梯度
形态学梯度,膨胀图与腐蚀图之差,用于保留目标物体的边缘轮廓。形态学梯度操作能描述图像亮度变化的剧烈程度;当我们想要突出高亮区域的外围时,则可以选用形态学梯度来突出边缘,可以保留物体的边缘轮廓。 形态学梯度的应用,如下图所示,可以看出,利用形态学梯度,可以很好地区分图像不同区域的灰度变化,所以,在图像分割领域,形态学梯度有很好的应用。公式(K是卷积核,F是待处理灰度图):
1.2 形态平滑
形态平滑,使用开运算和闭运算做形态平滑,循环执行开运算-闭运算-开运算操作,交替顺序,不断增大的结构元素来执行开-闭滤波。利用形态学开运算和闭运算可以实现图像的形态学平滑(也可以称之为图像除噪)处理,想象一下,假如有一块高低不平的田地,为了使这块平整这块土地,你需要挖掉高处的土,填到田地的低洼处,而闭运算就相当于挖掉高处的土,开运算就相当于将在高处挖掉的图填至低处。所以,按照这个原理,利用开运算和闭运算就可以实现图像的平滑,
本次算法设计采用了 10 次开-闭运算操作。
利用开运算和闭运算实现的形态学平滑,具有计算量大,复杂度较高等缺点,俄日了应对这一问题,可以直接使用膨胀和腐蚀来实现这一运算,其实现公式如下所示:
1.3 高帽变换(顶帽)
高帽变换(顶帽),是原图与原图的开运算的差值图像。开运算放大了裂缝或者局部低亮度的区域,所以,从原图中减去开运算后的图,得到的结果突出了比原图轮廓周围的区域更明亮的区域,这个操作与选择的核的大小有关。TopHat 运算一般用来分离比邻近点亮一些的斑块,可以使用这个运算提取背景。
Top-hat Transform算法在中文里被称为“高帽算法”,简称为TT,Top-hat算法。提取不光滑背景中的图像特征时,Top-hat算法是一种非常有效的工具。按照Top-hat算法的实现方式,TT算法可以分为以下两类:
1.4 低帽运算(黑帽)
低帽运算(黑帽),是闭运算结果与原图的差值图像。黑帽运算的结果突出了比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。
Open-cv 中的 morphologyEx()函数可以用来执行灰度形态学的形态梯度、高帽变换、低帽变换等操作,本次算法设计用到的参数有:
MORPH_OPEN:开运算(Opening operation);
MORPH_CLOSE:闭运算(Closing operation);
MORPH_GRADIENT:形态学梯度:(Morphological gradient);
MORPH_TOPHAT:“顶帽”(“Top hat”);
MORPH_BLACKHAT :“黑帽”(“Black hat“)。
2 代码
运行代码说明
1.要改变代码中的图片地址(地址不能有中文)
更改
put(path)
函数中的路径put(r'../image/image1.jpg')
2.注意最后的
plt.savefig('1.new.jpg')
是保存plt图像,如果不使用可以注释掉代码依赖包:
matplotlib 3.4.2 numpy 1.20.3 opencv-python 4.1.2.30
# pip安装 pip install matplotlib numpy opencv-python
import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def put(path):
# 读取图片
img = cv2.imread(path, 0)
# 设置核
kernel = np.ones((5, 5), np.uint8)
kernel2 = np.ones((55, 55), np.uint8)
# 形态学梯度调用
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
# 形态平滑
# 使用开运算和闭运算做形态学平滑
# 10次交替开闭运算得到形态平滑结果
fasf = img.copy() # 用以存放交替开闭运算的形态平滑图像
for i in range(10):
# 图像开运算
fasf = cv2.morphologyEx(fasf, cv2.MORPH_OPEN, kernel)
# 图像闭运算
fasf = cv2.morphologyEx(fasf, cv2.MORPH_CLOSE, kernel)
# 高帽变换
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel2)
# 低帽变换
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel2)
# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(231), plt.imshow(img, plt.cm.gray), plt.title('原始图像'), plt.axis('off')
plt.subplot(232), plt.imshow(img, plt.cm.gray), plt.title('灰度图像'), plt.axis('off')
plt.subplot(233), plt.imshow(gradient, plt.cm.gray), plt.title('形态梯度(5 * 5核)'), plt.axis('off')
plt.subplot(234), plt.imshow(fasf, plt.cm.gray), plt.title('形态平滑(5*5核)'), plt.axis('off')
plt.subplot(235), plt.imshow(tophat, plt.cm.gray), plt.title('高帽变换(55 * 55核)'), plt.axis('off')
plt.subplot(236), plt.imshow(blackhat, plt.cm.gray), plt.title('低帽变换(55*55核)'), plt.axis('off')
# plt.savefig('4.new-img.jpg')
plt.show()
# 图像处理函数,要传入路径
put(r'../image/image3.jpg')