数学形态学是图像处理的重要工具,可用于获取图像边界、提取骨架、去除噪声和检测角点,其应用覆盖
文字识别、视觉检测和医学图像处理等领域。
形态变换是一些基于图像形状的简单操作。形态学处理主要针对的是二值图像(在图像中任何像素点的灰度值只有 0 或 255)
两种基本的形态学算子是腐蚀和膨胀。
结构元素(内核)
在考察目标图像各部分之间的关系时,需要设计一种收集信息的“探针”,即结构元素。
-
在图像中不断移动结构元素,就可以考察图像中各部间的关系。
-
结构元素的形状包括矩形、十字形、椭圆形和菱形等,如果结构元素长宽相等,矩形和椭圆形将退化为正方形和圆形。
-
一般来说,结构元素尺寸要明显小于目标图像的尺寸,选择不同形状和尺寸的结构元素可提取图像中的不同特征。
-
结构元素本身也是一个图像集合,对于结构元素可以指定一个原点,将其作为结构元素参与形态学运算的参考点。原点可包含在结构元素中,也可不包含在结构元素中。
腐蚀操作
原理:
腐蚀是一种最基本的数学形态学运算,对给定的目标图像 X 和结构元素 S,将 S 在图像上移动,则对于每一个当前位置 x 有
即 S 对 X 腐蚀的结果是S 完全包含在 X 中时 S 的原点位置的集合。
原始图像中的一个像素(无论是 1 还是 0)只有当内核下的所有像素都是 1 时才被认为是 1,否则它就会被侵蚀(变成 0)。
根据内核的大小,边界附近的所有像素都会被丢弃。
因此,前景物体的厚度或大小减小,或只是图像中的白色区域减小。它有助于去除小的白色噪声,分离两个连接的对象。
代码:
OpenCV 中采用 getStructuringElement()
和erode()
函数实现结构元素的设定和图像腐蚀操作
cv2.getStructuringElement(eleType,ksize,point)
-
eleType: 结构元素类型,OpenCV 中定义了 3 种基本结构元素形状
· MORPH_RECT 矩形 . MORPH_CROSS 十字形 . MORPH_ELLIPSE 椭圆形
-
ksize: 结构元素大小
-
point: 锚点(结构元素中心点)位置
dst=cv2.erode(src,kernel,iterations)
- kernel: 卷积核
- iterations: 迭代次数,默认为 1
import cv2 as cv
import numpy as np
img=cv.imread('pic.png',0)
# 通过getStructuringElement()设置结构元素
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3),(1,1))
# 还可以通过np.ones()函数设置卷积核
# kernel=np.ones((3,3),np.uint8)
# 腐蚀
erosion=cv.erode(img,kernel,iterations=2)
cv.imshow('original',img)
cv.imshow('erosion',erosion)
cv.waitKey(0)
cv.destroyAllWindows()
处理结果:
对比处理结果我们发现原图像中的白色噪声被腐蚀掉了。
膨胀操作
原理:
对给定的目标图像 X 和结构元素 S,将 S 在图像上移动,则对于每一个当前位置 x 有
即用 S 来膨胀 X 得到的集合是 S v S^{v} Sv的平移与 X 至少有一个公共的非零元素相交时,S 的原点位置的集合
( S v S^{v} Sv指 S 关于原点的映射)
与腐蚀操作相反(腐蚀虽然消除了白噪声,但也会压缩图像),但并不是互为逆运算,
如果内核下至少有一个像素为“ 1”,则像素元素为“ 1”,图像就会膨胀。因此,它会增加图像中的白色区域或增加前景对象的大小。
代码:
dst=cv.dilate(src,kernel,iterations)
- kernel: 卷积核
- iterations: 迭代次数,默认为 1,进行一次膨胀
import cv2 as cv
import numpy as np
img=cv.imread('pic.png',0)
# 使用numpy库生成卷积核
kernel=np.ones((5,5),np.uint8)
erosion=cv.erode(img,kernel,iterations=2)# 腐蚀
cv.imshow('erosion',erosion)
# 膨胀
k=np.ones((3,3),np.uint8) # 使用3*3的卷积核
dliate=cv.dilate(erosion,k)
cv.imshow('dilate',dliate)
cv.waitKey(0)
cv.destroyAllWindows()
处理结果:
这里我们将腐蚀过后的二值图像进行膨胀操作
由于腐蚀和膨胀并不是互为逆运算,所以它们可以结合使用。在腐蚀和膨胀两个基本运算的基础上,可以构造出形态学运算簇
开运算
先对图像进行腐蚀然后膨胀其结果,称为开运算。对于消除噪音很有用
代码:
import cv2 as cv
import numpy as np
pic2=cv.imread('pic2.png',0)
# 开运算
k=np.ones((5,5),np.uint8)
erode1=cv.erode(pic2,k,iterations=1)
dilate1=cv.dilate(erode1,k)
cv.imshow('original',pic2)
cv.imshow('open',dilate1)
cv.waitKey(0)
cv.destroyAllWindows()
或 open= cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
处理结果:
闭运算
先对图像进行膨胀然后腐蚀其结果,称为闭运算。
在关闭前景对象内部的小孔或对象上的小黑点时很有用。
代码:
import cv2 as cv
import numpy as np
pic1=cv.imread('pic1.png',0)
k=np.ones((5,5),np.uint8)
# 闭运算
dilate2=cv.dilate(pic1,k)
erode2=cv.erode(dilate2,k,iterations=1)
cv.imshow('original',pic1)
cv.imshow('close',erode2)
cv.waitKey(0)
cv.destroyAllWindows()
或 close = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
处理结果:
形态学梯度
图像膨胀与腐蚀运算之差
可以用形态学梯度来突出边缘,保留物体的边缘轮廓
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)
顶帽
原图与开运算之差
tophat = cv.morphologyEx(src, cv.MORPH_TOPHAT, kernel)
黑帽
闭运算与原图之差
blackhat = cv.morphologyEx(src, cv.MORPH_BLACKHAT, kernel)