图像形态学
简单来讲,形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。
是图像处理学科的一个单独分支学科
灰度与二值图像处理中重要手段
是由数学的集合论等相关理论发展起来的
最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。 他们的运用广泛:,在于:
消除噪声
分割(isolate)独立的图像元素,以及连接(join)相邻的元素。
寻找图像中的明显的极大值区域或极小值区域。
膨胀
此操作将图像 A 与任意形状的内核 (B),通常为正方形或圆形,进行卷积。
内核 B 有一个可定义的 锚点, 通常定义为内核中心点。
进行膨胀操作时,将内核 B 划过图像,将内核 B 覆盖区域的最大相素值提取,并代替锚点位置的相素。显然,这一最大化操作将会导致图像中的亮区开始”扩展” (因此有了术语膨胀 dilation )。对上图采用膨胀操作我们得到:
Dilation result - Theory example
背景(白色)膨胀,而黑色字母缩小了。
3*3的结构元素/模板
注意:腐蚀和膨胀都支持任意形状的结构元素
膨胀的作用:
对象大小增加一个像素(3*3)
平滑对象边缘
减少或者填充对象之间的距离
腐蚀
腐蚀在形态学操作家族里是膨胀操作的孪生姐妹。它提取的是内核覆盖下的相素最小值。
进行腐蚀操作时,将内核 B 划过图像,将内核 B 覆盖区域的最小相素值提取,并代替锚点位置的相素。
以与膨胀相同的图像作为样本,我们使用腐蚀操作。从下面的结果图我们看到亮区(背景)变细,而黑色区域(字母)则变大了。
完整代码
import cv2 as cv
import numpy as np
#腐蚀:背景腐蚀,中间的图片腐蚀了周围,增强对象边缘
def erode_demo(image):
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary",binary)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))
erode_dst=cv.erode(binary,kernel)
cv.imshow("erode_demo",erode_dst)
#膨胀:背景膨胀,中间图片被膨胀变小,平滑对象边缘
def dilate_demo(image):
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary",binary)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))#腐蚀形状为3*3的矩阵
dilate_dst=cv.dilate(binary,kernel)
cv.imshow("dilate_demo",dilate_dst)
src = cv.imread("D:/OpenCV/opencv/sources/samples/data/lena.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
#调用函数对二值化图像进行操作
erode_demo(src)
dilate_demo(src)
#直接对彩色图像对象操作
kernel=cv.getStructuringElement(cv.MORPH_RECT,(5,5))
erode_dst=cv.erode(src,kernel)
cv.imshow("erode_result",erode_dst)
dilate_dst=cv.dilate(src,kernel)
cv.imshow("dilate_result",dilate_dst)
cv.waitKey(0)
cv.destroyAllWindows()
print("Hi,python!")
运行结果
二值图像
可以看出,腐蚀图片(erode)中,背景图片被腐蚀,所以黑色的区域变粗。膨胀图片(dilate)中,背景图片膨胀,所以黑色区域变细。
彩色图像
可以看出,腐蚀图像(erode)中,背景被腐蚀,所以图像变暗。膨胀图像(dilate)中,背景膨胀,所以图像变亮。
函数补充说明
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))
erode_dst=cv.erode(binary,kernel)
dilate_dst=cv.dilate(binary,kernel)
进行 腐蚀 操作的函数是 erode 。 它接受了三个参数:
src: 原图像
erosion_dst: 输出图像
element: 腐蚀操作的内核。 如果不指定,默认为一个简单的 3x3 矩阵。否则,我们就要明确指定它的形状,可以使用函数 getStructuringElement:
Mat element = getStructuringElement( erosion_type,
Size( 2erosion_size + 1, 2erosion_size+1 ),
Point( erosion_size, erosion_size ) );
我们可以为我们的内核选择三种形状之一:
矩形: MORPH_RECT
交叉形: MORPH_CROSS
椭圆形: MORPH_ELLIPSE
然后,我们还需要指定内核大小,以及 锚点 位置。不指定锚点位置,则默认锚点在内核中心位置。
膨胀与腐蚀类似。