形态学主要从图像内提取分量信息,该分量信息通常对于表达和描绘图像的形状具有重要意义,通常是图像理解时使用的最本质的形状特征。
腐蚀是基础的形态学操作之一,能够将图像的边界点消除,使图像沿着边界向内收缩,也可以将小于指定结构体元素部分去除,借此实现出去噪声、元素分割等功能。
腐蚀过程中,通常使用一个核(结构元)来逐个像素地扫描要被腐蚀的图像,并根据核(结构元)的关系来确定腐蚀结果。腐蚀操作等形态学操作是逐个像素地来决定值的,每次判定的点都是与结构元中心点所对应的点。
腐蚀操作的语法:
dst = cv2.erode(src, kernal[, anchor[, interations[, borderType[,bordreValue]]]])
示例程序:
import cv2
import numpy as np
img = cv2.imread('dige.jpg')
kernal1 = np.ones((5,5),np.uint8)
kernal2 = np.ones((10,10),np.uint8)
erosion1 = cv2.erode(img,kernal1)
erosion2 = cv2.erode(img,kernal2)
cv2.imshow('img',img)
cv2.imshow('erosion1',erosion1)
cv2.imshow('erosion2',erosion2)
cv2.waitKey()
cv2.destroyAllWindows()
结果显示:
原始图像
使用(5,5)的核进行腐蚀操作的结果
使用(10,10)的核进行腐蚀操作
由结果可以看出,腐蚀操作将原始图像内的毛刺去掉了,而且在增大腐蚀核的同时,图像也遭到了更大的腐蚀。
膨胀操作是形态学里另一种基本操作。膨胀操作与腐蚀操作的作用是相反的,膨胀操作能对图像的边界进行扩张。膨胀操作对填补图像分割后图像内所存在的空白相当有帮助。同腐蚀过程一样,膨胀过程也是使用一个核(结构元)来逐个像素地扫描要被膨胀的图像,并根据核(结构元)和待膨胀图像的关系来确定膨胀结果。
在膨胀过程中,要将核(结构元)逐个像素地遍历整幅图像,并根据核(结构元)与待膨胀图像的关系来确定结果图像中与结构元中心点对应位置像素点的值。
膨胀操作的语法为:
dst = cv2.dilate(src, kernal[, anchor[, iterations[, borderType[,borderValue]]]])
cv2.erode()
内相对应参数含义一致。示例程序:
import cv2
import numpy as np
img = cv2.imread('ting.jpg')
kernal1 = np.ones((5,5),np.uint8)
dilation1 = cv2.dilate(img,kernal1)
dilation2 = cv2.dilate(img,kernal1,iterations=9)
cv2.imshow('img',img)
cv2.imshow('dilation1',dilation1)
cv2.imshow('dilation2',dilation2)
cv2.waitKey()
cv2.destroyAllWindows()
原始图像如下:
使用大小为(5,5)的核进行膨胀操作:
修改iterations = 9(默认值为1),表示迭代9次膨胀操作:
由结果可知,膨胀操作是将图像“变粗”的效果,iterations=9
是将膨胀操作连续重复9次。
腐蚀操作和膨胀操作是形态学运算的基础,将腐蚀和膨胀操作进行组合,就可以实现开运算、闭运算(关运算)、形态学梯度运算、礼帽运算(顶帽运算)、黑帽运算、击中击不中等多种不同形式的运算。
其语法如下:
dst = cv2.morphologyEx(src, op, kernel[, anchor[, iterations[, borderType[, borderValue]]]]])
cv2.erode()
内的相应参数的含义一致。开运算是将图像腐蚀,在对腐蚀的结果进行膨胀,可以用于去噪、计数等。
通过将函数cv2.morphologyEx()
中操作类型参数op设置为‘cv2.MORPH_OPEN
’,实现开运算,语法结构如下:
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernal)
示例程序:
import cv2
import numpy as np
img = cv2.imread('dige.jpg')
kernel = np.ones((10,10),np.uint8)
r = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()
结果如下:
从结果可以看出开运算将原始图像中的毛刺全部去除。
闭运算是先膨胀、后腐蚀的运算,它有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景图像进行连接。可以在函数cv2.morphologyEx()
中操作类型参数op设置为“cv2.MORPH_CLOSE()
”,可以实现闭运算。语法结构如下:
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernal)
示例程序:
import cv2
import numpy as np
img = cv2.imread('close.PNG',cv2.IMREAD_UNCHANGED)
k=np.ones((10,10),np.uint8)
r=cv2.morphologyEx(img,cv2.MORPH_CLOSE,k,iterations=3)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()
结果如下:
原图像
闭运算后
由结果可以看出,原图像中有许多黑点,当闭运算后,其中的黑点全部消失。
形态学梯度运算是用图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景图像的边缘。
通过将函数cv2.morphologyEx()
的操作类型参数op设置为‘cv2.MORPH_GRADIENT
’,可以实现形态学梯度运算。其语法结构如下:
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernal)
示例程序:
import cv2
import numpy as np
img = cv2.imread('ting.jpg',cv2.IMREAD_UNCHANGED)
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,k)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()
结果如下:
原图像
梯度运算后的结果
从结果可以看出,形态学梯度运算使用膨胀图像(扩张亮度)减腐蚀图像(收缩亮度),得到原始图像中前景对象的边缘。
礼帽运算是用原始图像减去其开运算图像的操作。礼帽运算能够获取图像的噪声信息,或者得到比原始图像边缘更亮的边缘信息。
通过将函数cv2.morphologyEx()
中操作类型参数op设置为“cv2.MORPH_TOPHAT
”,可以实现礼帽运算。其语法结构如下:
result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernal)
示例代码:
import cv2
import numpy as np
img = cv2.imread('dige.jpg',cv2.IMREAD_UNCHANGED)
K = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, K)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()
结果如下:
原始图像
礼帽运算后结果
由结果可以看出,原图像边缘的噪声被提取了出来。
黑帽运算是用闭运算图像减去原始图像的操作。黑帽运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。
通过将函数cv2.morphologyEx()中操作类型op设置为“cv2.MORPH_BLACKHAT
”,可以实现黑帽运算。语法如下:
result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernal)
示例代码如下:
import cv2
import numpy as np
img = cv2.imread('close.PNG')
kernel = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()
示例代码:
原始图像
黑帽运算结果
由结果可以看出,黑帽运算将原图片中的黑点提取了出来,并表示成了白色。
在进行形态学操作时,必须使用一个特定的核(结构元)。该核可以自定义生成,也可以通过函数cv2.getStructuringElement()
构造。该函能够构造并返回一个用于形态学处理所使用的结构元素。该函数的语法格式为:
retval = cv2.getStructuringElement(shape, ksize[, anchor])
该函数用来返回一个用于形态学操作的指定大小和形状的结构元素。
cv2.MORPH_RECT | 矩形结构元素,所有元素值都是1 |
---|---|
cv2.MORPH_CROSS | 十字形结构元素,对角线元素值为1 |
cv2.MORPH_ELLIPSE | 椭圆形结构元素 |
除了使用该函数,用户也可以自己构建任意二进制掩码作为形态学操作中所使用的结构元素。