备注
前往结尾 下载完整示例代码。或者通过 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')
基于观察到的 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()
脚本总运行时间: (0 分钟 36.325 秒)