Dibujar mallas de distancia entre vecinos#

Al estudiar las relaciones de vecindad entre células, por ejemplo, para determinar si las células pueden comunicarse entre sí, sus distancias entre sí son relevantes. Podemos visualizar estas utilizando mallas de distancia.

import pyclesperanto_prototype as cle
from numpy import random
from skimage.io import imread

Estamos utilizando un conjunto de datos publicado por Heriche et al. bajo licencia CC BY 4.0 disponible en el Image Data Resource.

raw_image = imread("../../data/plate1_1_013 [Well 5, Field 1 (Spot 5)].png")[:,:,0]

nuclei = cle.voronoi_otsu_labeling(raw_image, spot_sigma=15)

cle.imshow(nuclei, labels=True)
../_images/010a418108069486938af96db7cb13e0175786416345198f4e98d9a0df9d68dc.png

Por ejemplo, se puede dibujar una malla entre vecinos próximos, núcleos que están más cerca que una distancia máxima dada.

max_distance = 320

proximal_neighbor_mesh = cle.draw_mesh_between_proximal_labels(nuclei, maximum_distance=max_distance)

# hacemos las líneas un poco más gruesas para propósitos de visualización
proximal_neighbor_mesh = cle.maximum_box(proximal_neighbor_mesh, radius_x=5, radius_y=5)

cle.imshow(proximal_neighbor_mesh)
../_images/50df103449f85897bafbe73a5da4cd240ea98a2693fb91957eac2463972df6be.png
proximal_distance_mesh = cle.draw_distance_mesh_between_proximal_labels(nuclei, maximum_distance=max_distance)

# hacemos las líneas un poco más gruesas para propósitos de visualización
proximal_distance_mesh = cle.maximum_box(proximal_distance_mesh, radius_x=5, radius_y=5)

cle.imshow(proximal_distance_mesh)
../_images/9cc37b6a72541f57812e709f12bd0eb7712962951d529ffff6ec186167bcd4b9.png

Mallas de distancia en más detalle#

Para dibujar una malla de distancia, necesitamos combinar una matriz de distancia, una representación abstracta de las distancias de todos los objetos entre sí, con una matriz de vecindad, que representa qué células son vecinas.

Comenzamos con la matriz de distancia.

centroids = cle.centroids_of_background_and_labels(nuclei)

distance_matrix = cle.generate_distance_matrix(centroids, centroids)

# ignoramos las distancias al objeto de fondo
cle.set_column(distance_matrix, 0, 0)
cle.set_row(distance_matrix, 0, 0)

cle.imshow(distance_matrix, colorbar=True)
../_images/4ef6505fa7103c0ce3ef963872a4cfa70ce0a61e2be9ba2740de96ea5b2488a1.png

A continuación, debemos configurar una matriz que represente para cada núcleo (de izquierda a derecha) cuáles son sus n vecinos más cercanos.

proximal_neighbor_matrix = cle.generate_proximal_neighbors_matrix(distance_matrix, max_distance=max_distance)

cle.imshow(proximal_neighbor_matrix)
../_images/aa3400095525196f732e9c0138d37eca94384c403d0abba7c23d05a43e33858a.png
distance_touch_matrix = distance_matrix * proximal_neighbor_matrix

cle.imshow(distance_touch_matrix, colorbar=True)
../_images/4f2e5cf35f71c0c5ac19ce6db917791d09aa4f6ae7cd5e1eea472c13e0019fb6.png
distance_mesh1 = cle.touch_matrix_to_mesh(centroids, distance_touch_matrix)

# hacemos las líneas un poco más gruesas para propósitos de visualización
distance_mesh1 = cle.maximum_box(distance_mesh1, radius_x=5, radius_y=5)

cle.imshow(distance_mesh1, colorbar=True)
../_images/0007349ae6064e58d9a75a1d4fb6c3fc9ecf320ccae3d96c22f8827b22eaca59.png

Para verificar si los núcleos de arriba siguen siendo los centroides de la malla, los ponemos juntos en una imagen.

visualization = cle.maximum_images(nuclei > 0, distance_mesh1 > 0)

cle.imshow(visualization)
../_images/cede1d383e9956f09d5814b213496ed85b5ff09e74b232120f6100a363f245fe.png