注意
前往結尾以下載完整的範例程式碼。或透過 Binder 在您的瀏覽器中執行此範例
使用像素圖尋找物件的測地中心#
在各種影像分析情況下,將影像的像素或影像的區域視為網路或圖表會很有用,其中每個像素都與其鄰居(有或沒有對角線)相連。其中一種情況是尋找物件的測地中心,它是最接近所有其他點的點,如果您只允許在物件的像素上移動,而不是直線移動。這個點是在網路中具有最大接近中心性 [1] 的點。
在此範例中,我們建立骨架的這種像素圖,並找到該骨架的中心像素。這展示了它與質心(也稱為質量中心)的實用性,質心實際上可能落在物件之外。
參考文獻#
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage as ndi
from skimage import color, data, filters, graph, measure, morphology
我們首先載入資料:人類視網膜的影像。
retina_source = data.retina()
_, ax = plt.subplots()
ax.imshow(retina_source)
ax.set_axis_off()
_ = ax.set_title('Human retina')

我們將影像轉換為灰階,然後使用 Sato 血管性 濾波器
以更好地辨識影像中的主要血管。
retina = color.rgb2gray(retina_source)
t0, t1 = filters.threshold_multiotsu(retina, classes=3)
mask = retina > t0
vessels = filters.sato(retina, sigmas=range(1, 10)) * mask
_, axes = plt.subplots(nrows=1, ncols=2)
axes[0].imshow(retina, cmap='gray')
axes[0].set_axis_off()
axes[0].set_title('grayscale')
axes[1].imshow(vessels, cmap='magma')
axes[1].set_axis_off()
_ = axes[1].set_title('Sato vesselness')

根據觀察到的血管性值,我們使用 遲滯 閾值處理
來定義主要血管。
thresholded = filters.apply_hysteresis_threshold(vessels, 0.01, 0.03)
labeled = ndi.label(thresholded)[0]
_, ax = plt.subplots()
ax.imshow(color.label2rgb(labeled, retina))
ax.set_axis_off()
_ = ax.set_title('Thresholded vesselness')

最後,我們可以 骨架化
此標籤影像,並使用它作為基礎來尋找該骨架中的 中心 像素
。將其與質心的位置進行比較!
largest_nonzero_label = np.argmax(np.bincount(labeled[labeled > 0]))
binary = labeled == largest_nonzero_label
skeleton = morphology.skeletonize(binary)
g, nodes = graph.pixel_graph(skeleton, connectivity=2)
px, distances = graph.central_pixel(
g, nodes=nodes, shape=skeleton.shape, partition_size=100
)
centroid = measure.centroid(labeled > 0)
_, ax = plt.subplots()
ax.imshow(color.label2rgb(skeleton, retina))
ax.scatter(px[1], px[0], label='graph center')
ax.scatter(centroid[1], centroid[0], label='centroid')
ax.legend()
ax.set_axis_off()
ax.set_title('Vessel graph center vs centroid')
plt.show()

腳本的總執行時間: (1 分 22.863 秒)