计算机视觉--opencv(代码详细教程)(三)--图像形态学
OpenCV 图像形态学详细介绍
图像形态学(Morphology)是基于形状对图像进行处理的数学分支,主要通过结构元素(Structuring Element) 与图像的交互来实现图像分析和处理。OpenCV 作为开源计算机视觉库,提供了丰富的形态学操作函数,广泛应用于图像去噪、边缘检测、目标分割、形状分析等领域。
一、形态学基础概念
1. 结构元素(Structuring Element)
结构元素是形态学操作的核心工具,本质是一个具有特定形状(如矩形、圆形、十字形)的小矩阵,用于定义操作的 “局部邻域”。
作用:通过滑动遍历图像,与图像中的像素进行交互(如比较、运算),决定输出像素的值。
OpenCV 定义方式:
使用cv2.getStructuringElement(shape, ksize)
生成,其中:shape
:结构元素形状(cv2.MORPH_RECT
矩形、cv2.MORPH_ELLIPSE
椭圆、cv2.MORPH_CROSS
十字形)。ksize
:结构元素大小(如(3,3)
、(5,5)
),尺寸越大,操作强度越高。
import cv2 # 生成3x3矩形结构元素 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
2. 二值图像与灰度图像的形态学
形态学操作最初针对二值图像(像素值仅为 0 或 255)设计,后续扩展到灰度图像:
- 二值图像:操作基于像素是否为 “前景”(255)。
- 灰度图像:操作基于像素值的大小(如最大值、最小值)
二、基本形态学操作
OpenCV 中最基础的形态学操作包括腐蚀、膨胀、开运算、闭运算,均通过 cv2.morphologyEx()
或专用函数实现。
1. 腐蚀(Erosion)
原理
结构元素在图像上滑动,仅当结构元素完全覆盖前景像素时,中心像素才保留为前景,否则变为背景。
- 效果:缩小前景区域,消除小噪声、断开连接区域。
OpenCV 实现
# # 1、图像腐蚀,函数为:
# # cv2.erode(src, kernel, dst,anchor,iterations,borderType,borderValue)
# # src:输入的图像
# # kernel:用于腐蚀的结构元素如果 element = Mat (),则使用 3 * 3 的矩形结构单元。
# # dst:是与 src 相同的大小和类型的输出图像。
# # iterations: 腐蚀操作的迭代次数,默认 1 次。次数越多,腐蚀操作执行的次数越多,腐蚀效果越明显
sun = cv2.imread ('sun.png')
cv2.imshow ('winname',sun)
cv2.waitKey (0)
kernel = np.ones ((3,3),np.uint8)
erosion_1 = cv2.erode(sun,kernel,iterations=2)
cv2.imshow('erosion_1',erosion_1)
cv2.waitKey(0)
应用场景
- 去除图像中的小亮点噪声。
- 分离重叠的物体(如粘连的字符)。
2. 膨胀(Dilation)
原理
结构元素在图像上滑动,只要结构元素与前景像素有交集,中心像素就变为前景。
- 效果:扩大前景区域,填补小空洞、连接断裂区域。
OpenCV 实现
# # 2、图像膨胀,函数为:
# # cv2.dilate(img, kernel, iteration)
# # 参数含义:
# # img - 目标图片
# # kernel - 进行操作的内核,默认是 3x3 的矩阵
# # iterations - 膨胀次数,默认是 1
wenzi = cv2.imread('wenzi.png')
cv2.imshow('src2',wenzi)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
wenzi_new = cv2.dilate(wenzi,kernel,iterations=2)
cv2.imshow('wenzi_new',wenzi_new)
cv2.waitKey(0)
应用场景
- 修复目标边缘的小缺口。
- 增强目标区域的连通性。
3. 开运算(Opening)
原理
先腐蚀后膨胀(开运算 = 膨胀(腐蚀(图像))
)。
- 效果:消除小噪声、平滑目标边缘,同时基本保持目标大小不变。
OpenCV 实现
zhiwen = cv2.imread('zhiwen.png')
cv2.imshow('zhiwen', zhiwen)
# cv2.waitKey(0)
kernel = np.ones((2,2), np.uint8) # 设置kernel大小
zhiwen_new = cv2.morphologyEx(zhiwen, cv2.MORPH_OPEN, kernel) # 开运算
cv2.imshow('zhiwen_new', zhiwen_new)
cv2.waitKey(0)
应用场景
- 去除图像中的孤立小噪声点(如老照片的斑点)。
- 分离紧密相连的物体。
4. 闭运算(Closing)
原理
先膨胀后腐蚀(闭运算 = 腐蚀(膨胀(图像))
)。
- 效果:填补目标内部的小空洞、连接断裂的区域,保持目标大小基本不变。
OpenCV 实现
zhiwen_duan = cv2.imread('zhiwen_duan.png')
cv2.imshow('zhiwen)duan', zhiwen_duan)
# cv2.waitKey(0)
kernel = np.ones((4,4), np.uint8) # 设置kernel大小
zhiwen_new = cv2.morphologyEx(zhiwen_duan, cv2.MORPH_CLOSE, kernel) # 闭运算
cv2.imshow('zhiwen_new_new', zhiwen_new)
cv2.waitKey(0)
应用场景
- 修复目标内部的小孔洞(如文字中的断笔)。
- 连接目标的断裂部分(如道路分割中的断开路段)。
三、高级形态学操作
基于基础操作的组合,OpenCV 还提供了更复杂的形态学操作,用于边缘检测、梯度计算等。
1. 形态学梯度(Morphological Gradient)
原理
膨胀结果减去腐蚀结果(梯度 = 膨胀(图像) - 腐蚀(图像)
)。
- 效果:突出目标的边缘轮廓,边缘宽度与结构元素大小相关。
OpenCV 实现
gradient = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)
wenzi = cv2.imread('wenzi.png')
cv2.imshow('wenzi',wenzi)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
#膨胀
pz_wenzi = cv2.dilate(wenzi,kernel,iterations=1)
cv2.imshow('pz_wenzi',pz_wenzi)
cv2.waitKey(0)
#腐蚀
fs_wenzi = cv2.erode(wenzi,kernel,iterations=1)
cv2.imshow('fs_wenzi',fs_wenzi)
cv2.waitKey(0)
#膨胀加腐蚀
bianyuan = cv2.morphologyEx(wenzi,cv2.MORPH_OPEN,kernel)
cv2.imshow('dianyuan',bianyuan)
cv2.waitKey(0)
cv2.destroyAllWindows()
应用场景
- 提取目标的边缘轮廓(替代传统边缘检测算子如 Canny)。
2. 顶帽运算(Top Hat)
原理
原图减去开运算结果(顶帽 = 原图 - 开运算(图像)
)。
- 效果:突出图像中比周围亮且小于结构元素的区域(如小亮点噪声)。
OpenCV 实现
tophat = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)
应用场景
- 提取图像中的小面积亮区域(如医学图像中的微钙化点)。
3. 黑帽运算(Black Hat)
原理
闭运算结果减去原图(黑帽 = 闭运算(图像) - 原图
)。
- 效果:突出图像中比周围暗且小于结构元素的区域(如小暗点噪声)。
OpenCV 实现
python
blackhat = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)
应用场景
- 提取图像中的小面积暗区域(如缺陷检测中的黑点)。
sun = cv2.imread('sun.png')
cv2.imshow( 'sun_yuantu' ,sun)
cv2.waitKey(0)
kernel =np.ones( (2,2),np.uint8)#设置kenenel大小#开运算
open_sun=cv2.morphologyEx(sun,cv2.MORPH_OPEN,kernel)
cv2.imshow( 'open_sun',open_sun)
cv2.waitKey(0)
#顶帽
tophat =cv2.morphologyEx(sun,cv2.MORPH_TOPHAT,kernel)
cv2.imshow( 'TOPHAT',tophat)
cv2.waitKey(0)
#闭运算
close_sun=cv2.morphologyEx(sun,cv2.MORPH_CLOSE,kernel)
cv2.imshow('close_sun',close_sun)
cv2.waitKey(0)
#黑帽
blackhat =cv2.morphologyEx(sun,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow( 'BLACKHAT',blackhat)
cv2.waitKey(0)
4. 击中 - 击不中变换(Hit-or-Miss)
原理
通过两个结构元素(目标结构和背景结构)检测特定形状的区域,仅当目标结构匹配前景且背景结构匹配背景时,才标记为击中。
- 效果:精确检测特定形状的目标(如特定模式的纹理)。
OpenCV 实现
# kernel1为目标结构,kernel2为背景结构
hitmiss = cv2.morphologyEx(src, cv2.MORPH_HITMISS, kernel)
应用场景
- 模式识别(如检测特定符号、纹理)。
四、形态学操作的关键参数
结构元素形状与大小:
- 形状影响操作的方向性(如十字形对线性结构更敏感)。
- 大小决定操作强度(尺寸越大,腐蚀 / 膨胀效果越显著)。
迭代次数(Iterations):
多次迭代相当于使用更大的结构元素(如 2 次 3x3 腐蚀 ≈ 1 次 5x5 腐蚀)。图像类型:
二值图像需确保前景为 255、背景为 0;灰度图像操作基于像素值的极值计算。
五、总结
OpenCV 的图像形态学操作通过结构元素与图像的交互,实现了对图像形状的灵活调整和分析。从基础的腐蚀、膨胀到高级的梯度、顶帽运算,这些操作在图像处理中具有不可替代的作用。实际应用中需根据具体任务选择合适的操作类型、结构元素和参数,以达到最佳效果。