形态学 - 细化
形态学
2023-09-11 14:15:38 时间
目录
1. 原理介绍
形态学的细化主要由 击中-击不中 变换实现,其数学表达式为:
- 定义为 B 对前景像素集合 A 的细化
- 定义为 B 对前景像素集合 A 的 击中-击不中 变换
- 结构元 B 常用的有八个,如下图所示
细化的步骤为:
1. 用结构元B1 对 A 做 击中-击不中 变换,然后用原图减去变换的结果A1
2. 将上步的结果A1,用B2 做 击中-击不中 变换,然后用A1减去B2变换的结果得到A2
3 . 将八个结构元循环迭代 记作一次细化的迭代
4. 如果两次细化的迭代结果相同,则认为细化完成;否则,重复前面三步骤
循环停止的条件是:所有结构元遍历的结果不再出现变化的时候
2. 代码讲解
细化代码的步骤简单介绍:
首先定义八个 击中-击不中 变换的结构元
这里结构元的元素:
- 1 代表前景像素
- 0 代表不感兴趣的,对应的图像前景背景都可
- -1 代表背景像素
把 击中-击不中 变换看成一个模板匹配。和kernel 一样的图像才能输出
然后根据步骤做迭代操作
这里需要将处理前的图片保存,留着判断两次细化的步骤是否相同
然后,结构元B1 对图像做 击中-击不中 变换,将原图减去变换的结果得到ret1
将新的图像ret1 作为下次处理的图像...
这里只展示了前两次运算
最后,如果细化一次完成的话,处理完和处理前的结果相同,则退出循环While
- .all 可以理解两个矩阵是否元素对应相等
如果传入书上的二值图像:
这里将书上的图像进行0填充了,因为试了好多次,击中-击不中变换里面好像没有0填充。
换了好多参数和输入,都没有得到想要的结果,就手动加一层pad,这样库再怎么填充,我们只需要观察内部就行了
经常算法可以得到:
观察发现和书上的结果是一致的
注:这里没有转化成m连通的细化集合
3. code
完整代码为:
import numpy as np
import cv2
def thin(img): # 细化算法
# 8 个细化 kernel
B1 = np.array([[-1,-1,-1],[0,1,0],[1,1,1]])
B2 = np.array([[0,-1,-1],[1,1,-1],[1,1,0]])
B3 = np.array([[1,0,-1],[1,1,-1],[1,0,-1]])
B4 = np.array([[1,1,0],[1,1,-1],[0,-1,-1]])
B5 = np.array([[1,1,1],[0,1,0],[-1,-1,-1]])
B6 = np.array([[0,1,1],[-1,1,1],[-1,-1,0]])
B7 = np.array([[-1,0,1],[-1,1,1],[-1,0,1]])
B8 = np.array([[-1,-1,0],[-1,1,1],[0,1,1]])
while True: # 循环迭代
tmp = img # 将上一步的操作暂存
for i in range(8): # 循环迭代八次
ret1 = cv2.morphologyEx(img,cv2.MORPH_HITMISS,B1) # B1 对图像做 击中-击不中变换
ret1 = img - ret1 # 原图 减去 上一步击中-击不中的结果
ret2 = cv2.morphologyEx(ret1,cv2.MORPH_HITMISS,B2) # 将上步的结果作为新的输入
ret2 = ret1 - ret2
ret3 = cv2.morphologyEx(ret2,cv2.MORPH_HITMISS,B3)
ret3 = ret2 - ret3
ret4 = cv2.morphologyEx(ret3,cv2.MORPH_HITMISS,B4)
ret4 = ret3 - ret4
ret5 = cv2.morphologyEx(ret4,cv2.MORPH_HITMISS,B5)
ret5 = ret4 - ret5
ret6 = cv2.morphologyEx(ret5,cv2.MORPH_HITMISS,B6)
ret6 = ret5 - ret6
ret7 = cv2.morphologyEx(ret6,cv2.MORPH_HITMISS,B7)
ret7 = ret6 - ret7
ret8 = cv2.morphologyEx(ret7,cv2.MORPH_HITMISS,B8)
ret8 = ret7 - ret8
img = ret8 # 八次迭代完成 保存结果
if (img==tmp).all(): # 如果所有结构元遍历的结果不再发生变化,则操作完成
dst = img # 保留细化结果
break
return dst.astype(np.uint8)
a = np.array([
[0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,0,0,0],
[0,1,1,1,1,1,1,1,1,1,0,0,0],
[0,1,1,1,1,1,1,1,1,1,0,0,0],
[0,1,1,1,0,0,1,1,1,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0]
],dtype=np.uint8) * 255
img = cv2.imread('./char.png',0)
_,img_bin = cv2.threshold(img,120,255,cv2.THRESH_BINARY) # 二值化处理
ret = thin(img_bin.copy()) # 传入拷贝图像
cv2.imshow('img',np.hstack((img_bin,ret)))
cv2.waitKey()
cv2.destroyAllWindows()
处理的结果为:
图片顺序:原图、细化结果
效果还是理想的
相关文章
- matlab形态学图像处理之strel函数
- 数字图像处理 基于形态学和距离变换的颗粒分割算法
- PCL 渐进式形态学滤波
- 【深度学习】基于形态学的权重自适应图像去噪(Matlab代码实现)
- 基于多尺度形态学梯度进行边缘检测(Matlab代码实现)
- OpenCV实现开操作、闭操作、形态学梯度、顶帽、黑帽
- m基于形态学处理和边缘检测的人员跟踪检测算法matlab仿真
- 【youcans 的 OpenCV 例程200篇】115. 形态学操作之开运算
- 【youcans 的 OpenCV 例程200篇】113. 形态学操作之腐蚀
- Python学习笔记十之Opencv图像处理:阈值、滤波、形态学、梯度、轮廓提取、FFT
- 形态学处理用于目标分割:腐蚀、膨胀、开/闭运算、顶帽等
- Opencv 基本操作三 实现各个形态学处理并实现多图展示
- 如何使用OpenCV进行图像的形态学操作?
- 【OpenCV】Chapter8.形态学图像处理