顺序对象(重新)标记#

如上所述,根据具体用例,对图像中的对象进行顺序标记可能很重要。例如,如果我们传递一个缺少标签的标签图像,标签图像的后处理算法可能会崩溃。因此,我们应该知道如何顺序重新标记图像。

import numpy as np
from skimage.io import imread
from skimage.segmentation import relabel_sequential
import pyclesperanto_prototype as cle

我们的起点是一个包含1-8标签的标签图像,其中一些标签不存在:

label_image = imread("../../data/label_map_with_index_gaps.tif")
cle.imshow(label_image, labels=True)
../_images/51805c923c35709f24d6f0350c13be42a832a6352c02b05b0d89eb7504a3320d.png

当测量图像中的最大强度时,我们可以看到这个包含4个标签的标签图像显然没有按顺序标记。

np.max(label_image)
8

我们可以使用unique函数来确定存在哪些标签:

np.unique(label_image)
array([0, 1, 2, 4, 8], dtype=uint8)

顺序标记#

现在我们可以使用scikit-image的relabel_sequential()函数重新标记这个图像并删除这些间隔。我们输入_作为额外的返回变量,因为我们对它们不感兴趣。这是必要的,因为relabel_sequential函数返回三个东西,但我们只需要第一个。

relabeled, _, _ = relabel_sequential(label_image)

cle.imshow(relabeled, labels=True)
../_images/3ba6457cc995726598ebdc81386238075079725fa050bfd766321b040c813966.png

之后,唯一的标签应该是连续的:

np.unique(relabeled)
array([0, 1, 2, 3, 4], dtype=uint8)

pyclesperanto也有一个用于顺序重新标记标签图像的函数。结果应该与scikit-image的结果相同。它只是不返回额外的值。

relabeled1 = cle.relabel_sequential(label_image)

cle.imshow(relabeled1, labels=True)
../_images/3ba6457cc995726598ebdc81386238075079725fa050bfd766321b040c813966.png

恢复顺序标记#

在某些情况下,我们对标签图像应用一个操作,该操作返回一个具有较少标签的新标签图像,这些标签是顺序标记的,但标签身份丢失了。例如,当从标签图像中排除太小的标签时,就会发生这种情况。

large_labels = cle.exclude_small_labels(relabeled, maximum_size=260)

cle.imshow(large_labels, labels=True, max_display_intensity=4)
../_images/36f7ec9698b614553fae93f11f9805517e0f0c5ff9395649d8a2f2a612d437b8.png
np.unique(large_labels)
array([0, 1, 2], dtype=uint32)

为了恢复原始标签身份,我们需要将表示剩余标签的二进制图像与原始标签图像相乘。

binary_remaining_labels = large_labels > 0

cle.imshow(binary_remaining_labels)
../_images/c1423a2d9cd701d92e76baaea3eea0337cb0843c7be9208511df9b36b77de9ce.png
large_labels_with_original_identity = binary_remaining_labels * relabeled

cle.imshow(large_labels_with_original_identity, labels=True, max_display_intensity=4)
../_images/ba79843daab6429f7be86b46ff2fc6726f79e5eee587c077b33cea75b9e8f2fc.png
np.unique(large_labels_with_original_identity)
array([0., 1., 3.], dtype=float32)

现在我们可以得出结论,身份为2和4的标签太小,因此被排除了。