# 骨架提取-skeleton # 骨架提取屬於形態學處理范疇,放在skimage.morphology子模塊內 # 骨架提取,也叫二值圖像細化。將一個連通區域細化成一個像素的寬度,用於特征提取和目標拓撲表示。 # skimage.morphology子模塊提供了兩個函數用於骨架提取,分別是Skeletonize()函數和medial_axis()函數。 ## skimage.morphology.skeletonize(image) # 格式為:skimage.morphology.skeletonize(image) # 輸入和輸出都是一幅二值圖像。 # 例1: from skimage import morphology,draw import numpy as np import matplotlib.pyplot as plt #創建一個二值圖像用於測試 image = np.zeros((400, 400)) #生成目標對象1(白色U型) image[10:-10, 10:100] = 1 image[-100:-10, 10:-10] = 1 image[10:-10, -100:-10] = 1 #生成目標對象2(X型) rs, cs = draw.line(250, 150, 10, 280) for i in range(10): image[rs + i, cs] = 1 rs, cs = draw.line(10, 150, 250, 280) for i in range(20): image[rs + i, cs] = 1 #生成目標對象3(O型) ir, ic = np.indices(image.shape) circle1 = (ic - 135)**2 + (ir - 150)**2 < 30**2 circle2 = (ic - 135)**2 + (ir - 150)**2 < 20**2 image[circle1] = 1 image[circle2] = 0 #實施骨架算法 skeleton =morphology.skeletonize(image) #顯示結果 fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) ax1.imshow(image, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('original', fontsize=20) ax2.imshow(skeleton, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('skeleton', fontsize=20) fig.tight_layout() plt.show() #例2:利用系統自帶的馬圖片進行骨架提取 from skimage import morphology,data,color import matplotlib.pyplot as plt image=color.rgb2gray(data.horse()) image=1-image #反相 #實施骨架算法 skeleton =morphology.skeletonize(image) #顯示結果 fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) ax1.imshow(image, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('original', fontsize=20) ax2.imshow(skeleton, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('skeleton', fontsize=20) fig.tight_layout() plt.show() ## skimage.morphology.medial_axis(image, mask=None, return_distance=False) # medial_axis就是利用中軸變換方法計算前景(1值)目標對象的寬度,格式為: # skimage.morphology.medial_axis(image, mask=None, return_distance=False) # mask: 掩模。默認為None, 如果給定一個掩模,則在掩模內的像素值才執行骨架算法。 # return_distance: bool型值,默認為False. 如果為True, 則除了返回骨架,還將距離變換值也同時返回。這里的距離指的是中軸線上的所有點與背景點的距離。 #例3: import numpy as np import scipy.ndimage as ndi from skimage import morphology import matplotlib.pyplot as plt #編寫一個函數,生成測試圖像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] mask = np.zeros((l, l)) generator = np.random.RandomState(1) points = l * generator.rand(2, n**2) mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1 mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) return mask > mask.mean() data = microstructure(l=64) #生成測試圖像 #計算中軸和距離變換值 skel, distance =morphology.medial_axis(data, return_distance=True) #中軸上的點到背景像素點的距離 dist_on_skel = distance * skel fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ax1.imshow(data, cmap=plt.cm.gray, interpolation='nearest') #用光譜色顯示中軸 ax2.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation='nearest') ax2.contour(data, [0.5], colors='w') #顯示輪廓線 fig.tight_layout() plt.show()