OpenCV-Python通用形态学处理:morphologyEx与结构元详解
本文详解OpenCV-Python中通用形态学函数cv2.morphologyEx()的使用,涵盖开运算、闭运算、梯度、顶帽及黑帽运算。同时介绍cv2.getStructuringElement()生成矩形、十字形及椭圆形结构元的方法,提供完整代码示例与效果分析。
通用形态学函数
在前一篇博文中,我们讲解了形态学的基础操作:腐蚀与膨胀。将这两种基础操作进行组合,即可实现开运算、闭运算等更为复杂的形态学处理。
OpenCV库提供了通用的形态学处理函数cv2.morphologyEx(),其完整函数定义如下:
def morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):
上述参数大多已在之前章节介绍过,但需特别注意:输入图像src的数据类型必须为CV_8U、CV_16U、CV_16S、CV_32F或CV_64F中的一种。
此外,函数中还有一个关键参数op,用于指定具体的形态学运算类别。具体类别及其含义如表所示:
| 类型 | 说明 | 意义 | 操作 |
|---|---|---|---|
| cv2.MORPH_ERODE | 腐蚀 | 腐蚀 | erode() |
| cv2.MORPH_DILATE | 膨胀 | 膨胀 | dilate() |
| cv2.MORPH_OPEN | 开运算 | 先腐蚀后膨胀 | dilate(erode()) |
| cv2.MORPH_CLOSE | 闭运算 | 先膨胀后腐蚀 | erode(dilate()) |
| cv2.MORPH_GRADIENT | 形态学梯度运算 | 膨胀图减腐蚀图 | dilate()-erode() |
| cv2.MORPH_TOPHAT | 顶帽运算 | 原始图像减开运算所得图像 | src-open() |
| cv2.MORPH_BLACKHAT | 黑帽运算 | 闭运算所得图像减原始图像 | close()-src |
| cv2.MORPH_HITMISS | 击中击不中 | 前景背景腐蚀运算的交集。仅仅支持CV8UC1二进制图像 | intersection(erode(src),erode(src1)) |
开运算
根据上表,开运算的执行顺序是先对原图像进行腐蚀,再进行膨胀。该操作常用于去除噪声或进行物体计数。虽然去噪功能可通过单独的腐蚀操作实现,但下面我们将通过一个有趣的案例来演示计数操作。
import cv2
import numpy as np
img = cv2.imread("open.jpg",cv2.IMREAD_UNCHANGED)
kernel = np.ones((9,9), np.float32)
result = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel,iterations=5)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,图像中的不同区域被成功分离,处理效果如下所示:

闭运算
闭运算的执行顺序是先膨胀后腐蚀。它有助于封闭前景物体内部的小孔,去除物体表面的小黑点,或者将分离的前景图像连接在一起。接下来,我们将演示如何将上图中的两个独立部分连接起来。
import cv2
import numpy as np
img = cv2.imread("close.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((10, 10), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=7)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,原本分离的两个方块被连接为一个整体,具体效果如下所示:

形态学梯度运算
形态学梯度运算是通过计算膨胀图像与腐蚀图像的差值来实现的,该操作能够提取原始图像中前景物体的边缘。我们继续使用上一篇中使用的膨胀图像进行测试,相关代码如下:
import cv2
import numpy as np
img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,图像呈现出中空的效果,具体结果如下:

顶帽运算
顶帽运算是指用原始图像减去其开运算后的结果。该操作可用于提取图像中的噪声信息,或获取比原图像边缘更亮的边缘细节。例如,我们可以提取上图中的白色线条,具体代码如下:
import cv2
import numpy as np
img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,处理效果如下所示:

黑帽运算
黑帽运算是用闭运算后的图像减去原始图像。该操作可用于提取内部的小孔、前景色中的小黑点,或获取比原始图像边缘更暗的边缘部分。这里,我们使用之前的人物图像进行测试,代码如下:
import cv2
import numpy as np
img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,处理效果如下所示:

结构元函数
前文曾提及,结构元既可以是自定义的,也可以通过OpenCV提供的cv2.getStructuringElement()函数自动生成。以下是该函数的完整定义:
def getStructuringElement(shape, ksize, anchor=None):
shape参数用于指定结构元的形状类型,具体取值如下表所示:
| 类型 | 意义 |
|---|---|
| cv2.MORPH_RECT | 矩形结构元,所有元素值为1 |
| cv2.MORPH_CROSS | 十字形结构元,对角线元素值为1 |
| cv2.MORPH_ELLIPSE | 椭圆形结构元素 |
ksize参数用于指定结构元的大小。
anchor参数用于指定结构元的锚点位置,默认值为(-1, -1),即形状的中心。该参数仅与十字形结构元及锚点位置紧密相关;在其他情况下,锚点位置仅用于调整形态学运算的结果。
下面,我们将分别实现上述三种形状类型,具体代码如下:
import cv2
img = cv2.imread("open.jpg", cv2.IMREAD_UNCHANGED)
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT,(50,50))
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS,(50,50))
kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(50,50))
result1 = cv2.dilate(img,kernel1)
result2 = cv2.dilate(img,kernel2)
result3 = cv2.dilate(img,kernel3)
cv2.imshow("img", img)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.imshow("result3", result3)
cv2.waitKey()
cv2.destroyAllWindows()
运行代码后,各种形状的处理效果如下所示:

至此,关于OpenCV-Python通用形态学函数的介绍到此结束。如需了解更多OpenCV通用形态学函数相关内容,请搜索本站历史文章或继续浏览后续文章。感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









