我有一张二值图像,我使用Skimage库中的骨架方法来提取骨架线。但是两边边缘都有很多毛刺,我想把这些毛刺去除掉。
我的Python脚本是:
import skimage as ski
import skimage.io as io
import matplotlib.pyplot as plt
import numpy as np
from skimage.morphology import skeletonize
import matplotlib
matplotlib.rc("font",family='Microsoft YaHei')
image_path=r"./1089_8.jpg"
image=io.imread(image_path,as_gray=True)
skeleton1=skeletonize(image,method='zhang')
skeleton2=skeletonize(image,method='lee')
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(8, 4), sharex=True, sharey=True)
ax=axes.ravel()
ax[0].imshow(image, cmap=plt.cm.gray)
ax[0].axis('off')
ax[0].set_title('original', fontsize=20)
ax[1].imshow(skeleton1, cmap=plt.cm.gray)
ax[1].axis('off')
ax[1].set_title('Zhang_method', fontsize=20)
ax[2].imshow(skeleton2,cmap=plt.cm.gray)
ax[2].axis('off')
ax[2].set_title('lee_method',fontsize=20)
fig.tight_layout()
plt.show()
我想去除并删除这些毛刺。然后计算二值图像的长度。
结果应如图 (c) 所示。
输入图像的主要问题是您认为它是二进制,而实际上它只是“几乎二进制”:您正在使用 JPEG 图像,JPEG 通常使用有损压缩,因此会产生压缩伪影。您肉眼看不到这些压缩伪影,但它们仍然会干扰骨架化算法。
快速修复:使您的图像真正的二进制,例如通过替换
image=io.imread(image_path,as_gray=True)
与
# Threshold image: values > 127 become 1, values ≤ 127 become 0
image = (io.imread(image_path, as_gray=True) > 127).astype(np.uint8)
对我来说,这会产生张方法的以下骨架:
对于李的方法,我得到:
您仍然需要处理一些毛刺和第二个“臂”;然而,我不会认为这些是骨架化方法的失败,而是图像的实际内容。
这是重现上面结果的完整代码:
import skimage.io as io
from skimage.morphology import skeletonize
import numpy as np
# TODO: Adjust input and output paths as necessary
in_path = "stackoverflow/stackoverflow.jpg"
out_path_zhang = "stackoverflow/zhang.png"
out_path_lee = "stackoverflow/lee.png"
# Threshold image: values > 127 become 1, values ≤ 127 become 0
image = (io.imread(in_path, as_gray=True) > 127).astype(np.uint8)
skeleton_zhang = skeletonize(image, method="zhang").astype(np.uint8)
skeleton_lee = skeletonize(image, method="lee").astype(np.uint8)
io.imsave("stackoverflow/zhang.png", skeleton_zhang.astype(np.uint8) * 255)
io.imsave("stackoverflow/lee.png", skeleton_lee.astype(np.uint8) * 255)