Previniendo la fuga de etiquetas#

Un problema común al segmentar células en imágenes con tinción de membrana es la fuga de etiquetas. Cuando se utilizan algoritmos como la watershed con semillas, estas fugas pueden prevenirse mediante el filtrado de la imagen, por ejemplo, usando un filtro de máximo local.

import napari_segment_blobs_and_things_with_membranes as nsbatwm
from skimage.data import cells3d
import stackview
import pyclesperanto_prototype as cle
import matplotlib.pyplot as plt

Para fines de demostración, utilizamos la imagen de ejemplo cells3d de scikit-image.

image = cells3d()[:,0]
image.shape
(60, 256, 256)

Observamos un corte de ella en Z-Y. Por simplicidad en el código, omitiremos las etiquetas de los ejes del gráfico después de esta figura.

cle.imshow(image[:,:,128], max_display_intensity=20000, continue_drawing=True)
plt.xlabel("Y")
plt.ylabel("Z")
Text(0, 0.5, 'Z')
../_images/5fa45f5ed25d6df1d1d1e5eca0e881b1d47ca58bbe1cca0c5add0ba00cfe573f.png

Al aplicar el algoritmo de watershed con semillas a este conjunto de datos (en 3D), podemos ver que algunas etiquetas se filtran en Z. Se fusionan con la región fuera de la capa de tejido.

reference_labels = nsbatwm.local_minima_seeded_watershed(image, spot_sigma=9)

cle.imshow(reference_labels[:,:,128], labels=True)
../_images/f6048e2e232798c17a508da020dd352d4bc6c7b3785fb2a528f5f348534b9479.png

El problema puede reducirse aplicando un filtro de máximo a la imagen en bruto. Esto llevará a membranas más gruesas y, por lo tanto, a una menor probabilidad de que el algoritmo de watershed pueda filtrarse a través de agujeros en la membrana.

thicker_membranes = nsbatwm.maximum_filter(image, radius=2)

cle.imshow(thicker_membranes[:,:,128], max_display_intensity=20000)
../_images/350917ec65b360445b829ffa2025ab5b612030518b175a660309156e1218c0d6.png

La imagen de etiquetas resultante tiene menos etiquetas con fugas, pero también ha perdido precisión en los bordes de las etiquetas en todas las direcciones.

labels1 = nsbatwm.local_minima_seeded_watershed(thicker_membranes, spot_sigma=9)

cle.imshow(labels1[:,:,128], labels=True)
../_images/37f206a6b54e091a596eec8ea4dfe63181e0ae2526100a4a2271d53b901bde9b.png

Las fugas a menudo parecen ocurrir solo en la dirección Z, lo cual es un efecto de la función de dispersión de punto de las técnicas comunes de microscopía. Típicamente es anisotrópica y, por lo tanto, el microscopio no puede capturar las membranas en Z tan bien como en X e Y.

Para lidiar con este problema de fuga de etiquetas solo en X e Y y conservar algo de la precisión en Z, necesitamos aplicar un filtro de máximo donde podamos especificar diferentes radios en X, Y y Z.

thinker_membranes_in_x_y = cle.maximum_sphere(image, radius_x=2, radius_y=2, radius_z=0)

cle.imshow(thinker_membranes_in_x_y[:,:,128], max_display_intensity=20000)
../_images/fbb9a54a49579cffa51f659276b4c70ee612eaac0b78c38ae138127c87e25226.png
labels2 = nsbatwm.local_minima_seeded_watershed(thinker_membranes_in_x_y, spot_sigma=9)

cle.imshow(labels2[:,:,128], labels=True)
../_images/18b2d6c94b8606c09c4827620fb1eb9d050a74b02dc569d5475a4e844feeef5d.png

Excluyendo etiquetas en los bordes de la imagen en Z#

Las imágenes de capas individuales de tejido se adquieren comúnmente de manera que vemos algunos píxeles y luego etiquetas segmentadas fuera de la parte superior e inferior del tejido (en Z). Podemos eliminar esas etiquetas mientras mantenemos explícitamente aquellas que tocan el borde de la imagen en X e Y.

corrected_labels = cle.exclude_labels_on_edges(labels2, 
                                               exclude_in_x=False, 
                                               exclude_in_y=False, 
                                               exclude_in_z=True)

cle.imshow(corrected_labels[:,:,128], labels=True)
../_images/49246fbac963a5fa880bde0c3bbc0426bf6b7e1673588e7c8adf41a3fc4d9951.png

Obviamente, todavía perdemos una célula que se había filtrado en el área debajo del tejido. Sin embargo, podría ser imposible obtener un resultado perfecto.