本文总结了腐蚀,膨胀和开闭操作在二值图像上的应用,基于opencv给出了实例。
参考:《数字图像处理》(第三版) 冈萨雷斯
1、腐蚀
腐蚀的定义为:在二维整数空间中,存在集合A和B,则B对A的腐蚀记为:
其中,称为集合按照点的平移。
上面的定义含义是,B对A的腐蚀是一个用z平移的B包含在A中的所有的点z的集合。腐蚀缩小或细化了二值图像中的物体。可以将腐蚀视为形态学滤波,这种操作将小于结构元的图像细节从图像中滤除。
2、膨胀
膨胀的定义为:A和B是中的集合,B对A的膨胀为:
其中是集合的反射,即。
从膨胀的定义可以得知,B对A的膨胀是在保证和至少有一个元素是重叠的前提下,所有位移z的集合。膨胀会“增长”或“粗化”二值图像中的物体,这种特殊的方式和粗化的宽度由所用结构元来控制。
3、开操作和闭操作
结构元B对集合A的开操作表示为:
上式的含义是B对A的开操作就是B对A的腐蚀,紧接着用B对结果进行膨胀。
结构元B对集合A的闭操作表示为:
上式的含义是B对集合A的闭操作就是简单地用B对A膨胀,紧接着用B对结果进行腐蚀。
开操作一般会平滑物体的轮廓、断开较窄的狭颈并消除较细的突出物。
闭操作同样也会平滑轮廓的一部分,但与开操作相反,它通常会弥合较窄的间断和细长的沟壑,消除较小的孔洞,填补轮廓线中的断裂。
4、应用opencv实现腐蚀和膨胀
代码如下
# encoding:utf-8
import cv2
import numpy as np
kernel5 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
kernel10 = cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
img = cv2.imread("five.jpg")
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,binary_img = cv2.threshold(gray_img,0,255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
dilate_img = cv2.dilate(binary_img,kernel5) # 膨胀
erode_img = cv2.erode(binary_img,kernel5) # 腐蚀
H, W = binary_img.shape
gap = np.ones(shape=(H,W//10),dtype=np.uint8)*255
im = np.hstack([binary_img,gap,dilate_img,gap,erode_img])
cv2.imshow("",im)
cv2.waitKey(0)
open_img5 = cv2.dilate(erode_img,kernel5)
close_img5 = cv2.erode(dilate_img,kernel5)
im = np.hstack([binary_img,gap,open_img5,gap,close_img5])
cv2.imshow("",im)
cv2.waitKey(0)
open_img10 = cv2.dilate(erode_img,kernel10)
close_img10 = cv2.erode(dilate_img,kernel10)
im = np.hstack([binary_img,gap,open_img10,gap,close_img10])
cv2.imshow("",im)
cv2.waitKey(0)
膨胀和腐蚀的结果如下图所示,最左侧是原图经过二值化之后的图,中间是用5乘5的矩形结构元膨胀的图,右侧是腐蚀的图。可以看到原图笔画中存在一些狭窄的断裂,膨胀之后笔画变粗了一些,并且断裂消失了。腐蚀之后笔画变得更细,并且笔画之间的断裂变得更大。膨胀图中的噪点同样变大了,腐蚀图中虽然噪点消失了,但是笔画不连续。
使用5乘5开操作和闭操作的结果如下图所示,左侧是原图的二值图,中间是开操作的图,也就是先腐蚀再膨胀,可以看到腐蚀的时候已经去除了图中的噪点,膨胀操作让笔画显得更粗一些。右侧是闭操作图,即先膨胀再腐蚀,因为膨胀的时候噪点也放大了,因此经过腐蚀之后,还是存在噪点。
先使用5乘5腐蚀和膨胀,然后使用10乘10的结构元进行开闭操作,结果如下图所示。可以看到开操作和闭操作的图中,都没有噪点,并且笔画也更加连贯。