前言
在上文中我们介绍了形态学变换的内容以及如何实现腐蚀膨胀与开闭运算,在本章内容中,我们将学习其它类型的形态学变换,梯度变换,击中击不中变换,顶帽与黑帽运算
一、梯度变换
形态学梯度变换是形态学变换中的一种,它通过对图像进行膨胀和腐蚀操作,然后计算这两个操作的差值,以提取图像的边缘和轮廓。
梯度运算可以分为四种,分别为:基本梯度,内部梯度,外部梯度,方向梯度,其中前三种比较常用
基本梯度:
基本梯度是用膨胀后的图像减去腐蚀后的图像得到差值图像,称为梯度图像也是OpenCV中支持的计算形态学梯度的方法,而此方法得到梯度有被称为基本梯度。
内部梯度:
是用原图像减去腐蚀之后的图像得到差值图像,称为图像的内部梯度
外部梯度:
图像膨胀之后再减去原来的图像得到的差值图像,称为图像的外部梯度。
方向梯度:
方向梯度是使用X方向与Y方向的直线作为结构元素之后得到图像梯度,X的结构元素分布膨胀与腐蚀得到图像之后求差值得到称为X方向梯度,用Y方向直线做结构分别膨胀与腐蚀之后得到图像求差值之后称为Y方向梯度。
使用:
import os
import cv2
# 不同的结构元 大小为5*5
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
img = cv2.resize(cv2.imread(r"E:\PS\R-C.jpg",0), (256,256))
erode = cv2.erode(img,kernel1) # 选择矩形结构元进行腐蚀
dia = cv2.dilate(img,kernel1) # 选择矩形结构元进行膨胀
grad1 = dia - erode # 计算图像梯度
grad2 = dia - img # 计算图像外部梯度
grad3 = img - erode # 计算图像内部梯度
cv2.imshow("erode",erode)
cv2.imshow("dia",dia)
cv2.imshow("grad1",grad1)
cv2.imshow("grad2",grad2)
cv2.imshow("grad3",grad3)
cv2.waitKey(0)
效果图:
二、击中击不中变换
击中击不中变换(Hit-or-Miss Transform)是一种在图像处理中使用的技术,它用于检测图像中特定形状的特征,并只保留那些完全符合预定义的结构元素模式的区域。主要通过定义结构元素来匹配目标特征,从而在图像分析和处理中实现细节的检测、形状的识别以及图像的精确分割。
实现过程为:
- 定义结构元素:结构元素是用于探测图像的小尺寸像素集合,通常有“击中”和“击不中”两个部分。这两个部分定义了要检测形状的特征。
击中部分(A):这部分结构元素描述了目标对象必须存在的像素点。 击不中部分(B):这部分结构元素描述了目标对象不应该存在的像素点。 - 变换过程: 击中操作:将结构元素的击中部分(A)在图像上进行腐蚀操作,标记出所有可以与A完全匹配的像素点。击不中操作:将结构元素的击不中部分(B)在图像上进行腐蚀操作,但这次是检查B部分在对应位置上不应该有任何像素点。
- 结果:变换的结果是两个腐蚀结果的交集。只有那些同时在A的腐蚀结果中并且在B的腐蚀结果的补集中的点才会被标记为击中击不中变换的输出。
总结来说击中击不中变换通过定义包含“击中”和“击不中”部分的结构元素,对图像分别进行腐蚀操作以标记出必须存在和不应存在的像素点,最终通过取这两个腐蚀结果的交集来识别图像中符合特定形状特征的点。
所以,由此我们定义图像A和结构B的击中击不中变换为以下的运算:
上面的式子具体表述为:
1 利用结构B对原图像A进行腐蚀变换
2. 利用结构B的补集对图像A的补集进行腐蚀变换。
3. 对上述二者取交集得结果。
击中击不中变换能够精确地识别出图像中的特定结构,而不受图像中其他部分的影响。这种操作在细节识别和精确图像分析中非常有价值。
在opencv中可以通过 cv2.morphologyEx()实现击中击不中变换
使用:
import cv2
import numpy as np
# 读取图像,确保是二值图像
image = cv2.imread(r'D:\AI_tool\GFPGAN-master\1.jpg', cv2.IMREAD_GRAYSCALE)
_, binary_image = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY_INV)
# 定义结构元素
# 假设我们有一个3x3的结构元素,其中B是击中部分,D是击不中部分
B = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
# 进行击中击不中变换
A_opencv_HMT = cv2.morphologyEx(binary_image, cv2.MORPH_HITMISS, B)
# 显示结果
cv2.imshow('Original Image', binary_image)
cv2.imshow('Hit-or-Miss Transform', A_opencv_HMT)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
原图:
结果图:
三、顶帽与黑帽运算
顶帽运算(Top-Hat Transform)和黑帽运算(Black-Hat Transform)都是形态学运算,它们基于腐蚀和膨胀操作,用于增强图像中的特定特征或突出图像中的细节。
顶帽运算:
顶帽运算是通过从原图像中减去其开运算的结果来实现的。开运算:对图像进行腐蚀,然后对腐蚀后的图像进行膨胀,以消除图像中的小对象或细节。)
减法操作:将原图像与开运算的结果相减,从而突出原图像中的明亮区域或细节。
顶帽运算的应用包括:
- 增强图像中的明亮区域。
- 突出图像中的小物体或细节。
- 平滑大物体的表面而保留小物体。
黑帽运算:
黑帽运算是通过先对图像进行闭运算(即先膨胀后腐蚀)来填充小孔或暗区域,然后从原图像中减去闭运算的结果,以此突出原图像中的暗区域和细节,常用于增强图像中的凹陷部分或检测图像中的暗特征。
黑帽运算的应用包括:
- 增强图像中的暗区域。
- 突出图像中的凹陷或暗细节。
- 填补图像中的小孔或间隙。
在opencv中使用顶帽与黑帽运算只需要将cv2.morphologyEx()函数将op置为MORPH_TOPHAT/MORPH_BLACKHAT即可。
代码实现:
import os
import cv2
# 不同的结构元 大小为5*5
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
img = cv2.resize(cv2.imread(r"E:\PS\1701054563143.png",0), (256,256))
img2 = cv2.resize(cv2.imread(r"E:\PS\1701054586943.png",0), (256,256))
top = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel1) # 对图像img进行顶帽运算
black = cv2.morphologyEx(img2, cv2.MORPH_BLACKHAT, kernel1) # 对图像img2进行底帽运
cv2.imshow("img",img)
cv2.imshow("top",top)
cv2.imshow("img2",img2)
cv2.imshow("black",black)
cv2.waitKey(0)
效果: