Draw distance-meshes between neighbors#

When studying neighborhood-relationships between cells, e.g. to determine if cells can communicate with each other, their distances to each other are relevant. We can visualize those using distance meshes.

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

We’re using a dataset published by Heriche et al. licensed CC BY 4.0 available in the 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/06_mesh_with_distances_3_0.png

A mesh can for example be drawn between proximal neighbors, nuclei which are closer than a given maximum distance.

max_distance = 320

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

# we make the lines a bit thicker for visualization purposes
proximal_neighbor_mesh = cle.maximum_box(proximal_neighbor_mesh, radius_x=5, radius_y=5)

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

# we make the lines a bit thicker for visualization purposes
proximal_distance_mesh = cle.maximum_box(proximal_distance_mesh, radius_x=5, radius_y=5)

cle.imshow(proximal_distance_mesh)
../_images/06_mesh_with_distances_6_0.png

Distance meshes in more detail#

For drawing a distance mesh, we need to combine a distance matrix, an abstract representation of distances of all objects to each other with a neighborhood-matrix, which represents which cells are neighbors.

We start with the distance matrix.

centroids = cle.centroids_of_background_and_labels(nuclei)

distance_matrix = cle.generate_distance_matrix(centroids, centroids)

# we ignor distances to the background object
cle.set_column(distance_matrix, 0, 0)
cle.set_row(distance_matrix, 0, 0)

cle.imshow(distance_matrix, colorbar=True)
../_images/06_mesh_with_distances_8_0.png

Next, we should setup a matrix which represents for each nucleus (from the left to the right) which are its n nearest neighbors.

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

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

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

# we make the lines a bit thicker for visualization purposes
distance_mesh1 = cle.maximum_box(distance_mesh1, radius_x=5, radius_y=5)

cle.imshow(distance_mesh1, colorbar=True)
../_images/06_mesh_with_distances_12_0.png

To check if the nuclei from above are still the centroids of the mesh, we put both together in one image.

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

cle.imshow(visualization)
../_images/06_mesh_with_distances_14_0.png