opencv中的图像形态学处理
什么是图像形态学?这里的图像形态学指的是数学上的图像形态学。
本节的腐蚀和膨胀处理的都是二值化之后的图像,所以也可以称之为二值腐蚀和二值膨胀,与灰度腐蚀和灰度膨胀对应。
腐蚀和膨胀都是针对白色部分而言的(在二值图像中白色为255)。
腐蚀(erosion)
腐蚀是求局部最小值的过程,图像处理后的效果为白色减少、黑色增多。
适用的场景:
- 消除小的噪声点
- 断开相邻的物体
- 使物体整体缩小
膨胀(dilation)
膨胀是求局部最大值的过程,图像处理后的效果为白色增多、黑色减少。
适用的场景:
- 填补物体中的空洞
- 连接相邻的物体
- 使物体整体扩大
结构元素(核)的影响
结构元素的形状和大小会显著影响形态学操作的结果:
目前 opencv 有四种可选的核:矩形,椭圆形,十字形,菱形。
这些核实际上就是不同内容的二维矩阵。
腐蚀和膨胀的测试代码
下面是一段测试程序,用于演示腐蚀和膨胀的效果、不同核的处理效果。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('../photos/2.bmp')
assert img is not None, 'image is invalid'
print('img size:', img.size, img.shape)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img = img[0:500, 300:600]
cv.imwrite('../photos/2_1.bmp', img)
_, binary = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
k_size = (5, 5)
kernel = np.ones(k_size, np.uint8)
print('k_ones', kernel)
# erode result
erosion = cv.erode(binary, kernel)
# dialate result
dilation = cv.dilate(binary, kernel)
# 不同形状的核
rect_kernel = cv.getStructuringElement(cv.MORPH_RECT, k_size) # 矩形
ellipse_kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, k_size) # 椭圆形
cross_kernel = cv.getStructuringElement(cv.MORPH_CROSS, k_size) # 十字形
diamond_kernel = cv.getStructuringElement(cv.MORPH_DIAMOND, k_size) # 菱形
print('rect kernel', rect_kernel)
print('ellipse kernel', ellipse_kernel)
print('cross kernel', cross_kernel)
print('diamond kernel', diamond_kernel)
# 应用不同核的腐蚀
erosion_rect = cv.erode(binary, rect_kernel)
erosion_ellipse = cv.erode(binary, ellipse_kernel)
erosion_cross = cv.erode(binary, cross_kernel)
erosion_diamond = cv.erode(binary, diamond_kernel)
images = [img, binary, erosion, dilation,
erosion_rect, erosion_ellipse, erosion_cross, erosion_diamond]
titles = ['original', 'binary', 'erosion', 'dilation',
'erosion rect', 'erosion ellipse', 'erosion cross', 'erosion diamond']
for i in range(len(images)):
plt.subplot(2, 4, i + 1)
# plt.imshow(binary, 'gray', vmin=0, vmax=255)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.savefig('plot.png', bbox_inches='tight')
plt.show()
开运算(opening)
线腐蚀后膨胀,用于消除小物体和毛刺
闭运算(closing)
先膨胀后腐蚀,用于填充小孔和连接断裂
(全文完)