PythonOpenCV-图像变换-形态变换
0. 简介
形态变换主要用于二值图像的形状操作,形态变换的实现原理基于数字形态学。
数字形态学也称形态学,它主要从图像内部提取信息来描述图像形态。
形态变换主要包括腐蚀、膨胀和高级形态操作。
1. 形态学操作内核
形态操作会使用一个内核(也称结构元 )遍历图像,根据内核和图像的位置关系决定内核中心对应的图像像素点的输出结果。
内核可以是自定义的矩阵(NumPy数组),也可以是 cv2.getStructuringElement()函数返回的矩阵。
cv2.getStructuringElement()函数的基本格式如下:
retval = cv2.getStructuringElement(shape, ksize)
参数说明:
shape:内核的形状,可使用的常量包括 cv2.MORPH_RECT(矩形)、cv2.MORPH_CROSS(十字形) 和 cv2.MORPH_ELLIPSE (圆形)
ksize:内核的大小
代码示例:
import cv2 as cv img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) retval0 = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # 返回矩形矩阵 print('矩形:{}', retval0) retval1 = cv.getStructuringElement(cv.MORPH_CROSS, (5, 5)) # 返回十字形矩阵 print('十字形:{}', retval1) retval2 = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5)) # 返回椭圆形矩阵 print('椭圆形:{}', retval2)
运行结果:
矩形:{} [[1 1 1 1 1] [1 1 1 1 1] [1 1 1 1 1] [1 1 1 1 1] [1 1 1 1 1]] 十字形:{} [[0 0 1 0 0] [0 0 1 0 0] [1 1 1 1 1] [0 0 1 0 0] [0 0 1 0 0]] 椭圆形:{} [[0 0 1 0 0] [1 1 1 1 1] [1 1 1 1 1] [1 1 1 1 1] [0 0 1 0 0]]
2. 腐蚀
腐蚀操作遍历图像时,会根据内核和图像的位置决定内核中心对应的图像像素点的输出结果。
OpenCV 的 cv2.erode()函数用于实现腐蚀操作,其基本格式如下:
dst = cv2.erode(src, kernel[, anchor[, iterations[, borderType[, borderValue]]]])
参数说明:
dst:转换后的结果图像。
src:原图像
kernel:内核
anchor:锚点,默认值为(-1,-1),表示锚点为内核中心
iterations:腐蚀操作的迭代次数
borderType:边界类型,默认为 BORDER_CONSTANT
borderValue:边界值,一般由 OpenCV 自动确定
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 img_dst = cv.erode(img_src, kernel, iterations=1) # 腐蚀,迭代1次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
3. 膨胀
膨胀操作与腐蚀操作刚好相反,它对图像的边界进行扩张。
其执行遍历操作时,只有在内核完全处于前景外部时,内核中心对应像素点的值才设置为 0,否则设置为 1。
OpenCV的 cv2.dilate()函数用于实现膨胀操作,其基本格式如下:
dst = cv2.dilate(src, kernel[, anchor[, iterations[, borderType[, borderValue]]]])
参数说明:
dst:转换后的结果图像。
src:原图像
kernel:内核
anchor:锚点,默认值为(-1,-1),表示锚点为内核中心
iterations:腐蚀操作的迭代次数
borderType:边界类型,默认为 BORDER_CONSTANT
borderValue:边界值,一般由 OpenCV 自动确定
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 img_dst = cv.dilate(img_src, kernel, iterations=1) # 膨胀,迭代1次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
4. 高级形态操作
高级形态操作基于腐蚀和膨胀操作,包括开运算、闭运算、形态学梯度运算、黑帽运算和礼帽运算等。
OpenCV的cv2.morphologyEx()函数用于实现形态学操作,其基本格式如下:
dst = cv2.morphologyEx(src, op, kernel[, anchor[, iterations [, borderType[, borderValue]]]])
参数说明:
dst:转换后的结果图像。
src:原图像
op:形态操作类型。op 参数值为cv2.MORPH_ERODE 时执行腐蚀操作,op 参数值为 cv2.MORPH_DILATE 时执行膨胀操作
kernel:内核
anchor:锚点,默认值为(-1,-1),表示锚点为内核中心
iterations:腐蚀操作的迭代次数
borderType:边界类型,默认为 BORDER_CONSTANT
borderValue:边界值,一般由 OpenCV 自动确定
4-1. 开运算
开运算将先对图像执行腐蚀操作,再对腐蚀结果执行膨胀操作。
cv2.morphologyEx()函数的 op 参数值为 cv2.MORPH_OPEN 时,执行形态学的开运算操作。
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 op = cv.MORPH_CLOSE img_dst = cv.morphologyEx(img_src, op, kernel, iterations=5) # 开运算,迭代5次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
4-2. 闭运算
闭运算与开运算相反,它先对图像执行膨胀操作,再对膨胀结果执行腐蚀操作。
cv2.morphologyEx()函数的 op 参数值为 cv2.MORPH_CLOSE时,执行形态学的闭运算操作。
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 op = cv.MORPH_CLOSE img_dst = cv.morphologyEx(img_src, op, kernel, iterations=5) # 闭运算,迭代5次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
4-3. 梯度运算
形态学梯度运算原理是用图像的膨胀操作结果减去腐蚀操作结果。
cv2.morphologyEx()函数的 op 参数值为 cv2.MORPH_GRADIENT 时,执行形态学梯度运算操作。
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 op = cv.MORPH_GRADIENT img_dst = cv.morphologyEx(img_src, op, kernel, iterations=5) # 梯度运算,迭代5次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
4-4. 黑帽运算
黑帽运算原理是用图像的闭运算结果减去原图像。
cv2.morphologyEx()函数的 op 参数值为 cv2.MORPH_BLACKHAT时,执行形态学的黑帽运算操作。
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 op = cv.MORPH_BLACKHAT img_dst = cv.morphologyEx(img_src, op, kernel, iterations=5) # 黑帽运算,迭代5次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
4-5. 礼帽运算
礼帽运算原理是用原图像减去图像的开运算结果。
cv2.morphologyEx()函数的 op 参数值为 cv2.MORPH_TOPHAT 时,执行形态学的礼帽运算操作。
代码示例:
import cv2 as cv import numpy as np、 img_src = cv.imread('./Pictures/lena.jpg', cv.IMREAD_GRAYSCALE) cv.imshow('src', img_src) # 获取内核方法1: kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # 获取内核方法2: # kernel = np.ones((5, 5), np.uint8) # 定义大小为5×5的内核 op = cv.MORPH_TOPHAT img_dst = cv.morphologyEx(img_src, op, kernel, iterations=5) # 礼帽运算,迭代5次 cv.imshow('dst', img_dst) # 显示转换结果图像 cv.waitKey(0)
运行结果:
/*-------------------------------------------------------------------------------------------------------
笔者说明:
该笔记来源于本人学习Python + OpenCv时的资料,
分享出来只是为了供大家学习,并且为了自己以后想要用的时候方便寻找。
时间:2023年8月22日
------------------------------------------------------------------------------------------------------------*/