所有相关接口验证demo以上传至仓库
代码地址:https://gitee.com/norep/learn-opencv
图像形态学
-
指一系列处理图像形状特征的图像处理技术;
-
形态学的基本思想是利用一种特殊的结构元(本质上就是卷积核)来测量或提取输入图像中相应的形状或特征,以便进一步进行图像分析和目标识别;
-
这些处理方法基本是对二进制图像进行处理,即黑白图像;
-
卷积核决定着图像处理后的效果;
-
形态学常用基本操作有:
-
膨胀与腐蚀
-
开运算
-
闭运算
-
顶帽
-
黑帽
-
各种形态学操作的作用
形态学操作 | 原理 | 作用 |
---|---|---|
形态学开运算 | 腐蚀 + 膨胀 | 去除图形外部的噪声 |
形态学闭运算 | 膨胀 + 腐蚀 | 去除图形内部的噪声 |
形态学梯度 | 膨胀 - 腐蚀 | 图形边缘 |
顶帽操作 | 原图 - 开运算 | 获取图形外部的噪声 |
黑帽操作 | 原图 - 闭运算 | 获取图形内部的噪声 |
形态学卷积核
在形态学处理中,总需要一个卷积核输入处理接口,一般可以通过手动创建一个矩阵使用,但在OpenCV中有更方便的方法创建这个卷积核。
OpenCV中提供了用于图像形态学处理的卷积核生成函数,使用这个函数,只需要简单的参数,就可以自动创建一个卷积核,用于后续的形态学操作。
kernel = cv2.getStructuringElement(shape, size, anchor=None, borderType=cv2.BORDER_DEFAULT)
参数说明:
-
shape:一个整数,表示结构元素的形状。
-
size:一个元组 (rows, cols),表示结构元素的大小。如果 rows 和 cols 都是 1,则表示结构元素是一个点(即单个像素)。
-
anchor:一个可选的元组 (x, y),表示结构元素锚点的坐标。默认值为 (0, 0),即结构元素的中心。
-
borderType:一个可选的整数,表示边界类型。
返回值:
- kernel:一个 NumPy 数组,表示创建的结构元素。
常见的形状包括:
-
cv2.MORPH_RECT:矩形结构元素。
-
cv2.MORPH_CROSS:十字形结构元素。
-
cv2.MORPH_ELLIPSE:椭圆形结构元素。
常见的边界类型包括:
-
cv2.BORDER_CONSTANT
-
cv2.BORDER_REPLICATE 等。
不同形状卷积的操作效果
形状 | 效果 |
---|---|
矩形卷积核 | 图像操作效果最强,范围最大 |
十字形卷积核 | 图像操作范围最小 |
椭圆形卷积核 | 图像操作范围略小于矩形卷积核 |
腐蚀与膨胀
膨胀与腐蚀操作的简单理解为,膨胀操作将会扩大白色像素面积,腐蚀操作会缩小白色像素面积。
腐蚀
腐蚀操作,是一种形态学图像处理技术。腐蚀操作通过使用一个结构元素(或核)来缩小图像中的对象。
腐蚀操作是使用卷积核扫描图像,一般使用全为1的卷积核,如果卷积核内的像素全是白色, 那么卷积结果就是白色,如果有任意一个像素为黑色,则卷积结果为0。
dst = cv2.erode(src, kernel, iterations=1, borderType=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0))
参数说明:
-
src:一个 NumPy 数组,表示要进行腐蚀操作的源图像。这个图像应该是一个二值图像。
-
kernel:一个 NumPy 数组,表示用于腐蚀操作的结构元素。这个结构元素应该是一个单通道数组,通常包含 0 和 1 的值。
-
iterations:一个整数,表示腐蚀操作的迭代次数。默认值为 1。
-
borderType:一个整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。
-
borderValue:一个可选的元组 (b, g, r),用于指定边界值。这个值将在图像的边界像素上应用。
返回值:
- dst:一个 NumPy 数组,表示腐蚀操作后的结果图像。
举例
使用矩形卷积核
pic1_gray = cv2.imread(pic_path, cv2.IMREAD_GRAYSCALE)
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 腐蚀
img = cv2.erode(pic1_gray, M, iterations=1)
cv2.imshow(windowName, img)
下面是原图与腐蚀操作后的效果对比
膨胀
膨胀操作是腐蚀操作的相反操作,原理为只要卷积核的锚点是非零值,那么所有卷积核覆盖的像素值均设置为非零值。
一般膨胀操作用于对腐蚀操作后,将被缩小的图像进行进行膨胀,还原原始图像中白色像素的面积。
dst = cv2.dilate(src, kernel, iterations=1, borderType=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0))
参数说明:
-
src:一个 NumPy 数组,表示要进行膨胀操作的源图像。这个图像应该是一个二值图像。
-
kernel:一个 NumPy 数组,表示用于膨胀操作的结构元素。这个结构元素应该是一个单通道数组,通常包含 0 和 1 的值。
-
iterations:一个整数,表示膨胀操作的迭代次数。默认值为 1。
-
borderType:一个整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。
-
borderValue:一个可选的元组 (b, g, r),用于指定边界值。这个值将在图像的边界像素上应用。
返回值:
- dst:一个 NumPy 数组,表示膨胀操作后的结果图像。
举例
pic1_gray = cv2.imread(pic_path, cv2.IMREAD_GRAYSCALE)
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 膨胀
img = cv2.dilate(pic1_gray, M, iterations=1)
cv2.imshow(windowName, img)
下面是膨胀操作对图像进行处理的对比,膨胀前与膨胀后对比
开运算与闭运算
开运算与闭运算是另一种去除图像噪声的思路
开运算与闭运算是对腐蚀与膨胀的基本应用
开运算 = 腐蚀 + 膨胀
闭运算 = 膨胀 + 腐蚀
OpenCV提供了接口执行形态学操作,如腐蚀、膨胀、开运算和闭运算。这个函数提供了对图像进行形态学处理的灵活性,允许用户选择不同的操作和结构元素。
dst = cv2.morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=1, borderType=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0))
参数说明:
-
src:一个 NumPy 数组,表示要进行形态学操作的源图像。这个图像应该是一个二值图像。
-
op:一个整数,表示要执行的形态学操作类型。
-
kernel:一个 NumPy 数组,表示用于形态学操作的结构元素。这个结构元素应该是一个单通道数组,通常包含 0 和 1 的值。
-
dst:一个可选的 NumPy 数组,用于存储形态学操作的结果。如果提供了这个参数,函数将返回 dst 而不是创建一个新数组。
-
anchor:一个可选的元组 (x, y),表示结构元素锚点的坐标。默认值为 (0, 0),即结构元素的中心。
-
iterations:一个可选整数,表示形态学操作的迭代次数。默认值为 1。
-
borderType:一个可选整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。
-
borderValue:一个可选的元组 (b, g, r),用于指定边界值。这个值将在图像的边界像素上应用。
返回值:
- 如果指定了 dst 参数,函数将返回 dst 数组;否则,函数将返回形态学操作后的结果图像数组。
常见的操作类型包括:
-
cv2.MORPH_ERODE:腐蚀操作。
-
cv2.MORPH_DILATE:膨胀操作。
-
cv2.MORPH_OPEN:开运算(腐蚀后膨胀)。
-
cv2.MORPH_CLOSE:闭运算(膨胀后腐蚀)。
-
cv2.MORPH_GRADIENT:梯度运算(膨胀与腐蚀之差)。
-
cv2.MORPH_TOPHAT:顶帽运算(原图像与开运算结果之差)。
-
cv2.MORPH_BLACKHAT:黑帽运算(闭运算结果与原图像之差)。
开运算
形态学开运算 = 腐蚀 + 膨胀 = 去除图形外部的噪声
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 形态学开运算 = 腐蚀 + 膨胀 = 去除图形外部的噪声
img = cv2.morphologyEx(pic1_gray, cv2.MORPH_OPEN, M, iterations=1)
闭运算
形态学闭运算 = 膨胀 + 腐蚀 = 去除图形内部的噪声
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 形态学闭运算 = 膨胀 + 腐蚀 = 去除图形内部的噪声
img = cv2.morphologyEx(pic1_gray, cv2.MORPH_CLOSE, M, iterations=1)
形态学梯度
形态学梯度 = 膨胀 - 腐蚀 = 边缘
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 形态学梯度 = 膨胀 - 腐蚀 = 边缘
img = cv2.morphologyEx(pic1_gray, cv2.MORPH_CLOSE, M, iterations=1)
顶帽与黑帽
顶帽操作
顶帽操作 = 原图 - 开运算 = 图像外部的噪点
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 顶帽操作 = 原图 - 开运算 = 图像外部的噪点
img = cv2.morphologyEx(pic1_gray, cv2.MORPH_TOPHAT, M, iterations=1)
黑帽操作
黑帽操作 = 原图 - 闭运算 = 获取图形内部的噪声
# 获取形态学卷积核
M = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 黑帽操作 = 原图 - 闭运算 = 获取图形内部的噪声
img = cv2.morphologyEx(pic1_gray, cv2.MORPH_BLACKHAT, M, iterations=1)