图像的形态学处理是基于图像形状的处理,主要有膨胀,腐蚀,开运算,闭运算等等,下面通过一些例子,逐一介绍。
腐蚀
腐蚀操作主要用来增长或者粗化二值图像中的黑色部分,也就是说,被腐蚀的是图像中的白色部分,使用OpenCV可以很简单的完成图像的腐蚀处理。代码如下所示:
image = cv2.imread(r'pics/circle.png')
kernel = np.ones((10, 10), np.uint8)
erosion = cv2.erode(image, kernel, iterations=1)
plt.subplot(121), plt.imshow(image), plt.title('Origin')
plt.subplot(122), plt.imshow(erosion), plt.title('Erode')
plt.show()
可以看到,黑线变粗了,而白色的部分被腐蚀了,可以自己调整核的大小,体会一下效果。
膨胀
膨胀与腐蚀正好相反,膨胀使得白色部分变得更多,看一下代码:
image = cv2.imread(r'pics/circle.png')
kernel = np.ones((5, 5), np.uint8)
dilate = cv2.dilate(image, kernel, iterations=1)
plt.subplot(121), plt.imshow(image), plt.title('Origin')
plt.subplot(122), plt.imshow(dilate), plt.title('Dilate')
plt.show()
可以看到,我们的黑线变细了,同样可以调整一下核的大小,然后看看结果。
开运算
开运算就是先对图像进行腐蚀,然后再进行膨胀,由于腐蚀可以除去白色部分,膨胀可以增加白色部分,如果核的大小选取合适,可以用来处理黑色部分中的白色噪声。代码和结果如下所示
image = cv2.imread(r'pics/black_circle.png')
kernel = np.ones((5, 5), np.uint8)
open_img = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
plt.subplot(121), plt.imshow(image), plt.title('Origin')
plt.subplot(122), plt.imshow(open_img), plt.title('Open')
plt.show()
这里我们使用了morphologyEx函数,实际上也可以使用该函数进行腐蚀和膨胀操作,只需要替换第二个参数即可,该函数是所有形态学处理的最基本的函数。
闭运算
与开运算相反,先膨胀再腐蚀,闭运算常用来处理白色背景上的黑色部分。如下所示:
image = cv2.imread(r'pics/white_circle.png')
kernel = np.ones((5, 5), np.uint8)
close_img = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
plt.subplot(121), plt.imshow(image), plt.title('Origin')
plt.subplot(122), plt.imshow(close_img), plt.title('Close')
plt.show()
注意到,边框一定要比点的像素宽度大,也就是说闭运算去除的是比较小的部分,想一下膨胀和腐蚀的原理就会明白。
形态学梯度
最后我们再来看一种形态学处理——形态学梯度,形态学梯度被定义为膨胀与腐蚀之差,我们还以之前的圆环为例,如果理解了膨胀和腐蚀的原理,应该能够想到执行的结果了。
image = cv2.imread(r'pics/circle.png')
kernel = np.ones((5, 5), np.uint8)
gradient = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel)
plt.subplot(121), plt.imshow(image), plt.title('Origin')
plt.subplot(122), plt.imshow(gradient), plt.title('Gradient')
plt.show()
背景变黑是次要的,最关键的,我们看到了我们圆环中间的那一条细黑线,使用形态学梯度,我们能够获得图像的骨架。
以上就是OpenCV的一些形态学处理,使用morphologyEx函数还可以进行其他的形态学处理,另外,我们上面的核都是矩形核,如果希望使用椭圆或者十字形状的核,可以使用cv2.getStructuringElement()函数进行构造。
代码已上传至github