Voronoi tesselation#

Voronoi-tesselation is the process of subdividing an area accoding to a Voronoi-diagram. In bio-imaging this method can be used to estimate where cells touch each other in case imaging data does not allwo this, e.g. if no membrane marker was used.

from skimage.io import imread
import pyclesperanto_prototype as cle

To demonstrate tesselation, we first load an image showing some objects.

image = imread("../../data/blobs.tif")
cle.asarray(image)
cle._ image
shape(254, 256)
dtypefloat32
size254.0 kB
min8.0
max248.0

We also segment the nuclei in this image and label them.

#background_subtracted = cle.top_hat_sphere(image, radius_x=50, radius_y=50)
binary = cle.threshold_otsu(image)
labels = cle.connected_components_labeling_box(binary)
labels
cle._ image
shape(254, 256)
dtypeuint32
size254.0 kB
min0.0
max64.0

By dilating the labels, we fill up the space between them. We could do this in a loop:

for radius in range(0, 10, 2):
    dilated_labels = cle.dilate_labels(labels, radius=radius)
    
    print("Radius:", radius)
    cle.imshow(dilated_labels, labels=True)
Radius: 0
../_images/11_voronoi_tesselation_7_1.png
Radius: 2
../_images/11_voronoi_tesselation_7_3.png
Radius: 4
../_images/11_voronoi_tesselation_7_5.png
Radius: 6
../_images/11_voronoi_tesselation_7_7.png
Radius: 8
../_images/11_voronoi_tesselation_7_9.png

We can also do this with a single function call and fill up background intensity until its gone. This process is called Voronoi-Tesselation. The result is a Voronoi-label-image. You can also see it as a discrete Voronoi-diagram.

voronoi_label_image = cle.voronoi_labeling(labels)
voronoi_label_image
cle._ image
shape(254, 256)
dtypeuint32
size254.0 kB
min1.0
max64.0

An common alternative visualization is the corresponding label-edge-image.

label_edges = cle.detect_label_edges(voronoi_label_image)
label_edges
cle._ image
shape(254, 256)
dtypeuint8
size63.5 kB
min0.0
max1.0

Voronoi and Delauney diagrams#

There is a close relationship with the Delauney triangulation. Voronoi and Delauney diagrams are dual graphs. In the continuous case, you can compute the one from the other and vice-versa. In the discrete case, one can determine an estimation of the Delauney graph from a Voronoi-label-image by determining the label’s centroids and connecting them:

touching_neighbor_mesh = cle.draw_mesh_between_touching_labels(voronoi_label_image)
touching_neighbor_mesh
cle._ image
shape(254, 256)
dtypefloat32
size254.0 kB
min0.0
max1.0

By visualizing the label-edge-image and neighbor-mesh in the same image, their relationship becomes more obvious.

sum_image = cle.maximum_images(touching_neighbor_mesh * 2, label_edges)
cle.imshow(sum_image, labels=True)
../_images/11_voronoi_tesselation_15_0.png

Exercise#

Visualize the neighbor-mesh and the label-edges of this label_image together as shown above:

label_image = cle.artificial_tissue_2d(width=200, height=100)
label_image
cle._ image
shape(100, 200)
dtypeuint32
size78.1 kB
min1.0
max60.0