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/010a418108069486938af96db7cb13e0175786416345198f4e98d9a0df9d68dc.png](../_images/010a418108069486938af96db7cb13e0175786416345198f4e98d9a0df9d68dc.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/50df103449f85897bafbe73a5da4cd240ea98a2693fb91957eac2463972df6be.png](../_images/50df103449f85897bafbe73a5da4cd240ea98a2693fb91957eac2463972df6be.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/9cc37b6a72541f57812e709f12bd0eb7712962951d529ffff6ec186167bcd4b9.png](../_images/9cc37b6a72541f57812e709f12bd0eb7712962951d529ffff6ec186167bcd4b9.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/4ef6505fa7103c0ce3ef963872a4cfa70ce0a61e2be9ba2740de96ea5b2488a1.png](../_images/4ef6505fa7103c0ce3ef963872a4cfa70ce0a61e2be9ba2740de96ea5b2488a1.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/aa3400095525196f732e9c0138d37eca94384c403d0abba7c23d05a43e33858a.png](../_images/aa3400095525196f732e9c0138d37eca94384c403d0abba7c23d05a43e33858a.png)
distance_touch_matrix = distance_matrix * proximal_neighbor_matrix
cle.imshow(distance_touch_matrix, colorbar=True)
![../_images/4f2e5cf35f71c0c5ac19ce6db917791d09aa4f6ae7cd5e1eea472c13e0019fb6.png](../_images/4f2e5cf35f71c0c5ac19ce6db917791d09aa4f6ae7cd5e1eea472c13e0019fb6.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/0007349ae6064e58d9a75a1d4fb6c3fc9ecf320ccae3d96c22f8827b22eaca59.png](../_images/0007349ae6064e58d9a75a1d4fb6c3fc9ecf320ccae3d96c22f8827b22eaca59.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/cede1d383e9956f09d5814b213496ed85b5ff09e74b232120f6100a363f245fe.png](../_images/cede1d383e9956f09d5814b213496ed85b5ff09e74b232120f6100a363f245fe.png)