骨架提取,也叫二值图像细化。这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示。骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内。
morphology子模块提供了两个函数用于骨架提取,分别是skeletonize()函数和medial_axis()函数。
1)skeletonize()函数
在模块:skimage.morphology.skeletonize(binary_image)下:输入和输出都是二值图像。
安装地址:pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple
单张图片骨架提取,代码如下:
import cv2 from skimage import morphology import numpy as np img = cv2.imread('a.png', 0) # 读取图片 _,binary = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY_INV) # 二值化处理 cv2.imwrite("binary.png", binary) # 保存二值化图片 binary[binary==255] = 1 skeleton0 = morphology.skeletonize(binary) # 骨架提取 skeleton = skeleton0.astype(np.uint8)*255 cv2.imwrite("skeleton.png", skeleton) # 保存骨架提取后的图片
效果如下,上图是二值化图,下图是细化后图
多张图片批量骨架提取处理,代码如下:
import cv2 from skimage import morphology import numpy as np import glob import os imageList = glob.glob("imgs/*.png") # 读取原始图片路径 img_file = "skeletonize_data/" # 保存骨架化后的图片的路径 # 确认上述地址是否存在 if not os.path.exists(img_file): os.mkdir(img_file) # 批量处理图片 for item in imageList: # print(item) # imgs/293718492401.pdf10.png img = cv2.imread(item, 0) # 读取图片 _, binary = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY_INV) # 二值化处理 # cv2.imwrite("binary.png", binary) binary[binary==255] = 1 skeleton0 = morphology.skeletonize(binary) # 图片细化(骨架提取) skeleton = skeleton0.astype(np.uint8)*255 cv2.imwrite(img_file + item[5:], skeleton) # 此处skeleton就是你需要保存的图像文件
2)骨架提取函数 medial_axis()
medial_axis就是中轴的意思,利用中轴变换方法计算前景(1值)目标对象的宽度,格式为:
skimage.morphology.medial_axis(image, mask=None, return_distance=False)
mask: 掩模。默认为None, 如果给定一个掩模,则在掩模内的像素值才执行骨架算法。
return_distance: bool型值,默认为False. 如果为True, 则除了返回骨架,还将距离变换值也同时返回。这里的距离指的是中轴线上的所有点与背景点的距离。
单张图片骨架提取,代码如下:
# 图片细化(骨架提取)单张图片处理 import cv2 from skimage import morphology import numpy as np img = cv2.imread('a.png', 0) # 导入图片 _, binary = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY_INV) # 二值化处理 binary[binary==255] = 1 skel, distance =morphology.medial_axis(binary, return_distance=True) # 图片细化(骨架提取) dist_on_skel = distance * skel dist_on_skel = dist_on_skel.astype(np.uint8)*255 cv2.imwrite("xihua.png", dist_on_skel) # 保存骨架提取后的图片
效果如下:
多张图片批量骨架提取处理,代码如下:
# 图片细化(骨架提取)多张图片批量处理 import cv2 from skimage import morphology import numpy as np import glob import os imageList = glob.glob("imgs/*.png") # 读取原始图片 img_file = "data/" # 保存骨架化后的图片的地址 # 确认上述地址是否存在 if not os.path.exists(img_file): os.mkdir(img_file) # 批量处理图片 for item in imageList: # print(item) # imgs/293718492401.pdf10.png img = cv2.imread(item, 0) # 导入图片 _, binary = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY_INV) # 二值化处理 binary[binary==255] = 1 skel, distance = morphology.medial_axis(binary, return_distance=True) # 图片细化(骨架提取) dist_on_skel = distance * skel dist_on_skel = dist_on_skel.astype(np.uint8)*255 cv2.imwrite(img_file + item[5:], dist_on_skel) # 此处dist_on_skel就是你需要保存的图像文件