首页 > 解决方案 > Skimage 合并过度分割的区域

问题描述

我正在尝试将此图像拆分为九个单独的区域(重叠的圆形区域)。由于圆圈重叠,我认为分水岭分割将是最好的方法。我按照这个 scikit-image.org 示例对我的图像执行该技术,并且图像被过度分割,我得到 10 个片段而不是 9 个片段,正如使用 ndi.labels 函数检查的那样。

在 peak_local_max 函数中增加足迹的大小会引发分割不足的问题,所以我认为最好是过度分割然后组合应该是单个区域的区域。您可以在提供的输出中看到第八个圆圈被分成两个单独的区域。我使用 regionprops 函数来绘制边界框。

分段图像示例.png

import matplotlib.pyplot as plt
from scipy import ndimage as ndi

from skimage import io, img_as_uint
from skimage.filters import median, threshold_minimum
from skimage.morphology import disk, square, closing, watershed
from skimage.feature import peak_local_max


image_bw = ('example_binary.tif')

distance = ndi.distance_transform_edt(image_bw)
local_maxi_disk10 = peak_local_max(distance, indices=False, 
                                   footprint=np.ones((400, 400)), 
                                   labels=image_bw)

markers, num_features = ndi.label(local_maxi_disk10)
labels = watershed(-distance, markers, mask=image_bw)
print('Number of features (ndi.label):', num_features)

fig, axes = plt.subplots(1, 3, figsize=(10, 4), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(image_bw)
ax[0].set_title('Image Binary')
ax[1].imshow(-distance)
ax[1].set_title('Distances')
ax[2].imshow(labels)
ax[2].set_title('Separated objects')

for a in ax:
    a.set_axis_off()

plt.tight_layout()
plt.show()

最终目标是获取图像中属于每个单独圆圈的部分并将它们保存为自己的图像,因此要组合不完整的区域,我可以将它们的边界框加在一起。然而,似乎应该有一种方法可以组合来自 regionprops 的多个区域,甚至可能来自分水岭过程本身的不同标签。任何人都可以通过合并区域/标签来帮助我找出正确的方向吗?我还将附上我使用的二进制图像。

example_binary.tif

标签: pythonimage-segmentationscikit-imagewatershed

解决方案


您可能可以使用区域邻接图 (RAG),然后根据某些标准[1] [2] [3]合并节点。但是,找到正确的标准通常很困难。

如果您想手动完成,可以使用 NumPy 索引来完成:

import numpy as np

def merge_labels(labels_image,
                 labels_to_merge,
                 label_after_merge):
    labels_map = np.arange(np.max(labels_image) + 1)
    labels_map[labels_to_merge] = label_after_merge
    return labels_map[labels_image]

推荐阅读