8. 形态学图像处理索引
一、 形态学算法
- 形态学处理的主要应用是提取图像中用来表示和描述形状的元素和成分,例如提取边界、连通分量、凸壳和区域骨架。
二、孔洞填充
- 孔洞是被前景像素连成的边框包围的背景区域。书法作品图像中存在孔洞,在图像分割后也经常会有一些孔洞。
1、闭运算孔洞填充:
- 形态学闭运算可以用来实现孔洞填充,闭运算先膨胀后腐蚀操作,膨胀使白色高亮区域增加,孔洞会被填充,但需要准确设置核大小,因此不是通用的方法。
2、约束膨胀孔洞填充:
- 冈萨雷斯《数字图像处理(第四版)》提供了一种孔洞填充的形态学算法,构造一个元素为 0 的阵列
,其中对应孔洞的像素值为 1,采用迭代过程可以填充所有的孔洞:
%20%5Ccap%20I%5Ec%2C%20%5C%20k%3D1%2C2%2C3...)
先找到孔洞中的一个点,用结构元进行膨胀,然后用原始图像的补集进行约束(交集运算),不断迭代重复这一操作直到算法收敛,就得到孔洞填充图。
3、泛洪算法孔洞填充:
- OpenCV 中提供了一种孔洞填充方法“泛洪填充法”,也成为“漫水填充法“。
其原理是将像素点的灰度值视为高度,整个图像就像一张高低起伏的地形图,向洼地注水将会淹没低洼区域,从而实现孔洞填充。
三、例程
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 10.11 约束膨胀算法实现孔洞填充
# 本算法参考:冈萨雷斯《数字图像处理(第四版)》 9.5.2 孔洞填充
# 图像为二值化图像,255 白色为目标物,0 黑色为背景,要填充白色目标物中的黑色空洞
imgGray = cv2.imread("../images/imgBloodCell.png", flags=0) # flags=0 读取为灰度图像
ret, imgBin = cv2.threshold(imgGray, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) # 二值化处理
imgBinInv = cv2.bitwise_not(imgBin) # 二值图像的补集
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) # 构造 3×3 十字形结构元
F = np.zeros(imgBin.shape, np.uint8) # 构建阵列 F,并写入 BinInv 的边界值
F[:, 0] = imgBinInv[:, 0]
F[:, -1] = imgBinInv[:, -1]
F[0, :] = imgBinInv[0, :]
F[-1, :] = imgBinInv[-1, :]
# 循环迭代:对 F 进行膨胀,膨胀结果与 BinInv 进行 AND 操作
Flast = F.copy()
for i in range(1000):
F_dilation = cv2.dilate(F, kernel)
F = cv2.bitwise_and(F_dilation, imgBinInv)
if (F==Flast).all():
break # 结束迭代算法
else:
Flast = F.copy()
if i==100: imgF100 = F # 中间结果
print("iter ={}".format(i)) # 迭代次数
plt.figure(figsize=(9, 5))
plt.subplot(131), plt.axis('off'), plt.title("Origin")
plt.imshow(imgGray, cmap='gray', vmin=0, vmax=255)
plt.subplot(132), plt.title("Hole filled (iter=100)"), plt.axis('off')
plt.imshow(imgF100, cmap='gray', vmin=0, vmax=255)
plt.subplot(133), plt.title("Hole filled (iter={})".format(i)), plt.axis('off')
plt.imshow(F, cmap='gray', vmin=0, vmax=255)
plt.tight_layout()
plt.show()
四、资料
youcans_的博客:
https://blog.csdn.net/youcans/article/details/123415835