数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat 变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。
接下来介绍两种基本形态学运算和五种高级变换:
- 腐蚀和膨胀是最基本的形态学算子
(1)腐蚀:删除对象边界的某些像素。粗略的说,腐蚀可以使目标区域范围“变小”,其实质造成图像的边界收缩,可以用来消除小且无意义的目标物。
(2)膨胀:给图像中的对象边界添加像素。粗略地说,膨胀会使目标区域范围“变大”,使目标边界向外部扩张,可以用来填补目标区域中某些空洞以及消除包含在目标区域中的小颗粒噪声。 - 高级形态学变换:
(1)开运算: 先腐蚀再膨胀,能去除原图像的毛刺
(2)闭运算: 先膨胀再腐蚀,可清除小黑点
(3)梯度:膨胀图-腐蚀图,提取物体边缘
(4)顶/礼帽:原图像-开运算图,突出原图像中比周围亮的区域
(5)黑帽:闭运算图-原图像,突出原图像中比周围暗的区域
1. 腐蚀操作
cv2.erode(src, kernel, iteration)
参数:src 表示的是输入图片,kernel 表示的是方框的大小,iteration 表示迭代的次数
腐蚀操作原理:存在一个 kernel,比如(3, 3),在图像中不断的平移,在这个 9 方框中,哪一种颜色所占的比重大,9 个方格中将都是这种颜色。
aiolei.png原图:
代码:
import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# 定义显示图像函数cv_show()
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 腐蚀
img = cv2.imread("aiolei.png")
kernel = np.ones((3,3),np.uint8) #np.ones()返回一个全1的n维数组
erosion = cv2.erode(img,kernel,iterations = 1)
result = np.hstack((img, erosion))
cv_show("src : erosion",result)
plt.imshow(result)
比较不同的迭代次数对输出图像的影响:
#import、函数cv_show与前面一样,省略,仅修改下面
square = cv2.imread("square.png")
kernel = np.ones((30,30),np.uint8)
#不同的迭代次数
erosion_1 = cv2.erode(square,kernel,iterations = 1)
erosion_2 = cv2.erode(square,kernel,iterations = 2)
erosion_3 = cv2.erode(square,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv_show("square",res)
plt.imshow(res)
2. 膨胀操作
cv2.dilate(src, kernel, iteration)
膨胀操作原理:存在一个 kernel,在图像上进行从左到右,从上到下的平移,如果方框中存在白色,那么这个方框内所有的颜色都是白色。
#import、函数cv_show与前面一样,省略,仅修改下面
#膨胀
img = cv2.imread("aiolei.png")
kernel = np.ones((3,3),np.uint8)
dilate = cv2.dilate(img,kernel,iterations = 1)
result = np.hstack((img, dilate))
cv_show("src : dilate",result)
plt.imshow(result)
#import、函数cv_show与前面一样,省略,仅修改下面
square = cv2.imread("square.png")
kernel = np.ones((30,30),np.uint8)
#不同的迭代次数
dilate_1 = cv2.dilate(square,kernel,iterations = 1)
dilate_2 = cv2.dilate(square,kernel,iterations = 2)
dilate_3 = cv2.dilate(square,kernel,iterations = 3)
res = np.hstack((dilate_1,dilate_2,dilate_3))
cv_show("square",res)
plt.imshow(res)
3. 开运算与闭运算
开运算(open):先腐蚀后膨胀的过程,不明显改变其面积。
闭运算(close):先膨胀后腐蚀的过程。
OpenCV 中 morphologyEx() 函数是一种形态学变化函数。
cv2.morphologyEx(src, op, kernel)
参数:
(1)src 输入图;
(2)op 形态学方法:
MORPH_OPEN – 开运算
MORPH_CLOSE – 闭运算
MORPH_GRADIENT – 形态学梯度
MORPH_TOPHAT – 顶帽
MORPH_BLACKHAT – 黑帽
(3)kernel 运算内核:若为 NULL 时即使用参考点位于中心 3 x 3 的核;
#import、函数cv_show与前面一样,省略,仅修改下面
# 开:先腐蚀,再膨胀
img = cv2.imread("aiolei.png")
kernel = np.ones((5,5),np.uint8)
open = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
cv_show("open",open)
plt.imshow(open)
#import、函数cv_show与前面一样,省略,仅修改下面
# 闭:先膨胀,再腐蚀
img = cv2.imread("aiolei.png")
kernel = np.ones((5,5),np.uint8)
close = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)
cv_show("close",close)
plt.imshow(close)
4. 梯度运算
梯度 = 膨胀 - 腐蚀
形态学梯度(morph-grad):可以突出团块的边缘,保留物体的边缘轮廓。
#import、函数cv_show与前面一样,省略,仅修改下面
square = cv2.imread("square.png")
kernel = np.ones((7,7),np.uint8)
gradient = cv2.morphologyEx(square,cv2.MORPH_GRADIENT,kernel) #梯度
cv_show("gradient",gradient)
plt.imshow(gradient)
5. 顶帽与黑帽
顶帽 = 原图像 - 开运算图
黑帽 = 闭运算图 - 原图像
顶帽(top-hat):将突出比原轮廓亮的部分。
黑帽(black-hat):将突出比原轮廓暗的部分。
#import、函数cv_show与前面一样,省略,仅修改下面
img = cv2.imread("aiolei.png")
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) #顶帽
blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel) #黑帽
result = np.hstack((tophat,blackhat))
cv_show("tophat-blackhat",result)
plt.imshow(result)
本笔记记录学习OpenCV,若有错误,欢迎批评指正,学习交流。