Etiquetado secuencial de objetos (re-etiquetado)#

Como se mencionó anteriormente, dependiendo del caso de uso, podría ser importante etiquetar objetos en una imagen de forma secuencial. Por ejemplo, podría ser que un algoritmo de post-procesamiento para imágenes etiquetadas falle en caso de que pasemos una imagen etiquetada con etiquetas faltantes. Por lo tanto, debemos saber cómo re-etiquetar una imagen secuencialmente.

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

Nuestro punto de partida es una imagen etiquetada con etiquetas del 1 al 8, donde algunas etiquetas no están presentes:

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

Al medir la intensidad máxima en la imagen, podemos ver que esta imagen etiquetada que contiene 4 etiquetas obviamente no está etiquetada secuencialmente.

np.max(label_image)
8

Podemos usar la función unique para averiguar qué etiquetas están presentes:

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

Etiquetado secuencial#

Ahora podemos re-etiquetar esta imagen y eliminar estos vacíos usando la función relabel_sequential() de scikit-image. Estamos ingresando el _ como variables de retorno adicionales ya que no estamos interesados en ellas. Esto es necesario porque la función relabel_sequential devuelve tres cosas, pero solo necesitamos la primera.

relabeled, _, _ = relabel_sequential(label_image)

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

Después, las etiquetas únicas deberían ser secuenciales:

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

Pyclesperanto también tiene una función para re-etiquetar imágenes etiquetadas secuencialmente. Se supone que el resultado es idéntico al resultado en scikit-image. Simplemente no devuelve los valores adicionales.

relabeled1 = cle.relabel_sequential(label_image)

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

Revertir el etiquetado secuencial#

En algunos casos, aplicamos una operación a una imagen etiquetada que devuelve una nueva imagen etiquetada con menos etiquetas que están etiquetadas secuencialmente pero se pierde la identidad de la etiqueta. Esto sucede, por ejemplo, cuando se excluyen etiquetas de la imagen etiquetada que son demasiado pequeñas.

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)

Para restaurar las identidades de etiqueta originales, necesitamos multiplicar una imagen binaria que represente las etiquetas restantes con la imagen etiquetada original.

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)

Ahora podemos concluir que las etiquetas con identidades 2 y 4 eran demasiado pequeñas y, por lo tanto, fueron excluidas.