opencv 图像形态学转换

??学习不同的形态学操作,例如腐蚀,膨胀,开运算,闭运算等
??学习的函数有:cv2.erode(), cv2.dilate(), cv2.morphologyEx()等
原理
??形态学操作是根据图像形状进行的简单操作,一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,梯度等。
1、腐蚀
??就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉,卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为 0),所以前景物体会变小,这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。
??这里个例子,使用一个 5x5 的卷积核,其中所有的值都是1。

import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((5,5),np.uint8) erosion = cv2.erode(img, kernel,iterations=1) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(erosion),plt.title('erosion') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

2、 膨胀
??与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小,所以再对其进行膨胀,这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((5,5),np.uint8) dilation = cv2.dilate(img, kernel,iterations=1) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(dilation),plt.title('dilation') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

3 、开运算 ??先进行腐蚀再进行膨胀就叫做开运算,被用来去除噪声。这里我们用到的函数是 cv2.morphologyEx()。
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((5,5),np.uint8) for i in range(2000): temp_x = np.random.randint(0,img.shape[0]) temp_y = np.random.randint(0,img.shape[1]) img[temp_x][temp_y] = 255 opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(opening),plt.title('opening') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

4、 闭运算 ??先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/3.png') kernel = np.ones((5,5),np.uint8) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(closing),plt.title('closing') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

5 、形态学梯度
??其实就是一幅图像膨胀与腐蚀的差别,结果看上去就像前景物体的轮廓。
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((5,5),np.uint8) gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(gradient),plt.title('gradient') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

6、 礼帽 原始图像与进行开运算之后得到的图像的差。9*9核
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((9,9),np.uint8) tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(tophat),plt.title('tophat') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

7 、黑帽 进行闭运算之后得到的图像与原始图像的差。
import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread('image/2.png') kernel = np.ones((9,9),np.uint8) blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel) plt.subplot(1,2,1),plt.imshow(img),plt.title('Original') plt.xticks([]),plt.yticks([]) plt.subplot(1,2,2),plt.imshow(blackhat),plt.title('blackhat') plt.xticks([]),plt.yticks([]) plt.show()

结果图:
opencv 图像形态学转换
文章图片

8 、形态学操作之间的关系
【opencv 图像形态学转换】我们把以上集中形态学操作之间的关系列出来以供大家参考
opencv 图像形态学转换
文章图片

参考:OpenCV官方教程中文版(For Python)

    推荐阅读