Python|OpenCV3图像形态学处理

图像的形态学处理是基于图像形状的处理,主要有膨胀,腐蚀,开运算,闭运算等等,下面通过一些例子,逐一介绍。
【Python|OpenCV3图像形态学处理】
腐蚀
腐蚀操作主要用来增长或者粗化二值图像中的黑色部分,也就是说,被腐蚀的是图像中的白色部分,使用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()


OpenCV使用erode函数进行腐蚀操作,其中kernel是一个核矩阵,我们可以将其想象为一块方形玻璃片,将玻璃片的中心依次放在图像中的白色像素上,如果玻璃片下的像素不全是白色像素,则将玻璃片下的白色像素替换为黑色像素;相反,如果玻璃片下的像素都是白色像素,则不对玻璃片下的像素进行处理。为了方便演示,我制作了一个圆环图片,然后对其进行腐蚀,结果如下图:
Python|OpenCV3图像形态学处理
文章图片



可以看到,黑线变粗了,而白色的部分被腐蚀了,可以自己调整核的大小,体会一下效果。
膨胀
膨胀与腐蚀正好相反,膨胀使得白色部分变得更多,看一下代码:
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()


使用dilate函数进行膨胀操作,同样需要传递一个核,同样把核想象为一个方形玻璃片,只不过与腐蚀相反,将玻璃片中心放置在白色像素,如果玻璃片下不全是白色像素,则将黑色像素改为白色,否则,不作处理。结果如图所示:
Python|OpenCV3图像形态学处理
文章图片



可以看到,我们的黑线变细了,同样可以调整一下核的大小,然后看看结果。


开运算
开运算就是先对图像进行腐蚀,然后再进行膨胀,由于腐蚀可以除去白色部分,膨胀可以增加白色部分,如果核的大小选取合适,可以用来处理黑色部分中的白色噪声。代码和结果如下所示
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()


Python|OpenCV3图像形态学处理
文章图片


这里我们使用了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()


Python|OpenCV3图像形态学处理
文章图片


注意到,边框一定要比点的像素宽度大,也就是说闭运算去除的是比较小的部分,想一下膨胀和腐蚀的原理就会明白。


形态学梯度
最后我们再来看一种形态学处理——形态学梯度,形态学梯度被定义为膨胀与腐蚀之差,我们还以之前的圆环为例,如果理解了膨胀和腐蚀的原理,应该能够想到执行的结果了。
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()


Python|OpenCV3图像形态学处理
文章图片


背景变黑是次要的,最关键的,我们看到了我们圆环中间的那一条细黑线,使用形态学梯度,我们能够获得图像的骨架。


以上就是OpenCV的一些形态学处理,使用morphologyEx函数还可以进行其他的形态学处理,另外,我们上面的核都是矩形核,如果希望使用椭圆或者十字形状的核,可以使用cv2.getStructuringElement()函数进行构造。

代码已上传至github
Python|OpenCV3图像形态学处理
文章图片




    推荐阅读