对于图片,可以通过形态学操作(如膨胀、腐蚀,开闭运算,梯度运算,礼貌黑帽等)对图像进行进一步的处理操作。

腐蚀操作

先加载一张灰度图

img = cv2.imread('dige.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

image.png
可以看到,原图像除了文字以外,有很多额外的延伸根须。

现在对其进行腐蚀操作:

kernel = np.ones((3,3),np.uint8) 
erosion = cv2.erode(img,kernel,iterations = 1)

cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

腐蚀操作的原理是生成一个核,这个核在图像中不断的平移,如上代码是一个3x3的核,则这个3x3的核在不断平移的过程中,将3x3方框内所占比重最大的颜色覆盖到整个3x3方框中,这样就完成了腐蚀操作。iterations为迭代次数。

腐蚀效果:
image.png

将iterations迭代次数改为3,查看不同迭代次数的影响:
image.png

同样,将核的大小改为6x6或9x9也会加大腐蚀的效果,因此对于腐蚀而言,选择合适的核大小和迭代次数很重要。

膨胀操作

同样以腐蚀操作所用的原始图片为例,我们对原始图片直接进行膨胀操作:

kernel = np.ones((3,3),np.uint8) 
dige_dilate = cv2.dilate(img,kernel,iterations = 1)

cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:
image.png
很明显可以看出,文字线条的粗细发生了变化。
膨胀操作和腐蚀操作的方法和原理类似,区别在于腐蚀操作所使用的是cv2.erode函数,而膨胀操作使用的是cv2.dilate函数。
在实际应用中,通常为了防止腐蚀操作对线条过于明显的腐蚀效果,从而在腐蚀操作后会追加一个膨胀操作,而这种先腐蚀再膨胀的方法,就被称之为开运算。

开运算和闭运算

前面说了什么是开运算,既然开运算是先腐蚀再膨胀,那么闭运算自然是先膨胀再腐蚀
再opencv中,对于开闭运算,有着一个简单的函数进行直接处理,而不需要如前面所述的那样麻烦:
cv2.morphologyEx(src, op, kernel)
参数说明:

  • src传入的图片
  • op进行变化的方式
  • kernel表示方框的大小

op = cv2.MORPH_OPEN 进行开运算,指的是先进行腐蚀操作,再进行膨胀操作

op = cv2.MORPH_CLOSE 进行闭运算, 指的是先进行膨胀操作,再进行腐蚀操作

开运算效果:
image.png

闭运算效果:
image.png

梯度运算

所谓梯度运算,就是膨胀操作后的图片-腐蚀操作后的图片
如下代码:

pie = cv2.imread('pie.png')
kernel = np.ones((7,7),np.uint8) 
dilate = cv2.dilate(pie,kernel,iterations = 5)
erosion = cv2.erode(pie,kernel,iterations = 5)

res =dilate-erosion
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

原图片为一张黑底白色圆图片,对其进行膨胀后的图片-腐蚀后的图片,效果如下:
image.png

使用前面所说的cv2.morphologyEx函数进行梯度运算:

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)

cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

image.png

可以看出,二者是有区别的。

礼帽与黑帽

  • 礼帽 = 原始输入-开运算结果
  • 黑帽 = 闭运算-原始输入
    礼帽与黑帽可以用来提取出处理后的图片与原始图片的区别部分。

礼帽和黑帽同样可以用cv2函数进行便携操作:
cv2.MORPH_TOPHAT:礼帽操作
cv2.MORPH_BLACKHAT:黑帽操作

礼帽操作

img = cv2.imread('dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()

image.png

可以看出,礼帽操作后,原始输入图片-腐蚀膨胀后的保留的文字部分,留下了多余的延生触须。

黑帽操作

img = cv2.imread('dige.png')
blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat ', blackhat )
cv2.waitKey(0)
cv2.destroyAllWindows()

image.png

黑帽操作可以看出闭运算与原始图片的差别。