形态变换主要用于二值图像的形状操作,形态变换的实现原理基于数字形态学。数字形态学也称形态学,它主要从图像内部提取信息来描述图像形态。形态学广泛应用于视觉检测、文字识别、医学图像处理、图像压缩编码等。形态变换主要包括腐蚀、膨胀和高级形态操作。
特别注意:图像的腐蚀和膨胀都是相较于高亮部分而言
形态变换是一些基于图像形状的简单操作。通常在二进制图像上执行,当然也可以在多通道图像上执行。它有两个输入,一个是我们的原始图像,而另外的一个是决定操作性质的结构元素或者说内核。正是基于这样的内核,才使得我们通过指定的方法实现关于内核下的形态变化。
形态变换包括:腐蚀、膨胀、开运算、闭运算、形态学梯度、顶帽操作、黑帽操作(用于二值化图像)膨胀与腐蚀是图像形态学最基础的两个操作,形态学的其它操作都是基于这两个操作基础上得到的,图像形态学是二值图像分析的重要分支学科。二值图像的腐蚀和膨胀就是将一个结构元素(小型二值图,一般为3*3大小)在一个大的二值图上逐点移动并进行比较,根据比较的结果作出相应处理而已。
对二值图像来说,白色被腐蚀即为黑色的膨胀,白色的膨胀就是黑色被腐蚀。要注意的是,膨胀和腐蚀都是不可逆的,即两者不能完全的相互抵消。
膨胀:结构元素的白点与要处理的图形对应像素点只要有一个相同,则该点设为白色,否则仍然为黑色。膨胀可以看成是最大值滤波,即用最大值替换中心像素点。
腐蚀:结构元素的白点与要处理的图形对应像素点全部相同,则该点为白色,否则变为黑色(即被腐蚀掉了)。腐蚀可以看出是最小值滤波,即用最小值替换中心像素点。
开操作:先腐蚀后膨胀的过程称为开运算:具有消除细小物体,来去除噪声,在纤细处分离物体和平滑较大物体边界的作用。
闭操作:先膨胀后腐蚀的过程称为闭运算:具有填充前景物体内细小空洞或者前景物体上的小黑点,连接邻近物体和平滑边界的作用。
形态学梯度:膨胀操作与腐蚀操作的差值,形态学梯度还包括内部梯度和方向梯度,作用:提取前景物体的轮廓。
顶帽操作:原图像与开操作的差值,作用:提取图像中的噪声。
黑帽操作:闭操作与原图像的差值,作用:突出噪声与原始图像的交界处,可近似表现出一些轮廓。
形态操作内核
retval = cv2.getStructuringElement(shape, ksize)
shape为内核的形状(矩形、十字形和椭圆形)
ksize为内核的大小
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
print("矩形矩阵\n",k1)
k2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
print("十字矩阵\n",k2)
k3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
print("椭圆形矩阵\n",k3)
打印结果:
侵蚀(Erosion)
内核区域存在的像素值全为1,整个区域才置1,否则置为0
其作用是,传入内核,实现对原输入图像的侵蚀——本质是侵蚀前景物体的边界。
其侵蚀的形式是——内核在图像中滑动(如2D卷积),仅在当内核下的所有像素均为1时,原始图像中的像素(1或0)才被视为1,否则它将被侵蚀(设为零)。
方法参数如下:
输入图像(src )
输入内核(kernel )
锚点(anchor )——默认为元素中心,一般不修改
迭代数(iterations)——也就是侵蚀次数
边界像素处理类型(borderType )——一般不设置
边界不变时的边界值(borderValue )——默认值
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
print("矩形矩阵\n",k1)
k2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
print("十字矩阵\n",k2)
k3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
print("椭圆形矩阵\n",k3)
img = cv2.imread('test01.png',0)
erosion1 = cv2.erode(img,k1,iterations = 1)
erosion2 = cv2.erode(img,k2,iterations = 1)
erosion3 = cv2.erode(img,k3,iterations = 1)
cv2.imshow("origion",img)
cv2.imshow("erosion1",erosion1)
cv2.imshow("erosion2",erosion2)
cv2.imshow("erosion3",erosion3)
cv2.waitKey(-1)
cv2.destroyAllWindows()
膨胀(Dilation)
内核区域存在像素值为1,整个区域就置1
方法参数如下:
- 输入图像(src )
- 输入内核(kernel )
- 锚点(anchor )——默认为元素中心,一般不修改
- 迭代数(iterations)——也就是扩张次数
- 边界像素处理类型(borderType )——一般不设置
- 边界不变时的边界值(borderValue )——默认值
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
print("矩形矩阵\n",k1)
k2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
print("十字矩阵\n",k2)
k3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
print("椭圆形矩阵\n",k3)
img = cv2.imread('test01.png',0)
erosion1 = cv2.dilate(img,k1,iterations = 1)
erosion2 = cv2.dilate(img,k2,iterations = 1)
erosion3 = cv2.dilate(img,k3,iterations = 1)
cv2.imshow("origion",img)
cv2.imshow("erosion1",erosion1)
cv2.imshow("erosion2",erosion2)
cv2.imshow("erosion3",erosion3)
cv2.waitKey(-1)
cv2.destroyAllWindows()
开运算 (Opening)
实现:开运算是通过先对图像腐蚀再膨胀实现的
dst = open( src, element) = dilate( erode( src, element ) )
作用:能够排除小团块物体(物体较背景明亮),可以消除高于邻近点的孤立点,达到去噪作用,可以平滑物体轮廓、断开较窄的狭颈。
import numpy as np
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.imread('tt.png',0)
r=cv2.morphologyEx(img,cv2.MORPH_OPEN,k1,1)
cv2.imshow("origion",img)
cv2.imshow("r",r)
cv2.waitKey(-1)
cv2.destroyAllWindows()
源文件
运行结果:
闭运算 (Closing)
实现:闭运算是通过先对图像膨胀再腐蚀实现的
dst = close( src, element) = erode( dilate( src, element ) )
作用:能够排除小型黑洞(黑色区域),可以消除低于邻近点的孤立点,达到去噪作用,可以平滑物体轮廓、弥合较窄的间断和细长的沟壑,消除小孔洞,填补轮廓线中的断裂。
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.imread('tt.png',0)
r=cv2.morphologyEx(img,cv2.MORPH_CLOSE,k1,1)
cv2.imshow("origion",img)
cv2.imshow("r",r)
cv2.waitKey(-1)
cv2.destroyAllWindows()
运行效果:
形态梯度(Morphological Gradient)
实现:膨胀图与腐蚀图之差
dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element )
作用:可以保留物体的边缘轮廓
import cv2
# 形态操作内核
k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.imread('tt.png',0)
r=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,k1)
cv2.imshow("origion",img)
cv2.imshow("r",r)
cv2.waitKey(-1)
cv2.destroyAllWindows()
运行效果:
顶帽(Top Hat)
实现:原图像与开运算结果图之差
dst = tophat( src, element ) = src - open( src, element )
作用:分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取
待补充测试
看一下对比图:
因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。
黑帽(Black Hat)
实现:闭运算结果图与原图像之差
dst = blackhat( src, element ) = close( src, element ) - src
作用:分离比邻近点暗的斑块,突出黑暗的区域
对比效果图:
因为黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关,所以,黑帽运算常用来分离比邻近点暗一些的斑块。
待补充测试