Overlay texts on images#

After labeling elements in an image, one may want to see some text over each element describing, for example, its area, or simply the label number of that element. One way to do that is using the matplotlib axes annotate function.

Previous related topics:

from skimage.io import imread
import matplotlib.pyplot as plt
from skimage import measure
import pyclesperanto_prototype as cle

We first open an image and label objects in it.

# Load data
blobs = imread('../../data/blobs.tif')
cle.asarray(blobs)
cle._ image
shape(254, 256)
dtypefloat32
size254.0 kB
min8.0
max248.0
labeled_blobs = cle.voronoi_otsu_labeling(blobs, spot_sigma=3.5)
labeled_blobs
cle._ image
shape(254, 256)
dtypeuint32
size254.0 kB
min0.0
max65.0

Then, we analyze the labeled elements and get their properties.

# Analyse objects
regionprops = measure.regionprops(labeled_blobs)

Finally, we use the axs.annotate() function with the following arguments:

  • text: the string to be displayed;

  • xy: the coordinates to plot the text;

  • fontsize: the size of the text;

  • color: the color of the text;

# Visualization
fig, axs = plt.subplots(1, 1)
cle.imshow(blobs, continue_drawing=True, plot=axs)
cle.imshow(cle.reduce_labels_to_label_edges(labeled_blobs), labels=True, plot=axs, continue_drawing=True, alpha=0.7)

# Plot label number over each element (iterate over each element)
for element in regionprops:
    # Get element centroid (x, y)
    element_centroid = (element.centroid[1]-8, element.centroid[0]+5)
    
    # Get element label and convert it to string
    element_label = str(element.label)
    
    # Plot label number at the coordinates of that element centroid
    axs.annotate(text = element_label, xy = element_centroid, fontsize = 12, color = 'white')
../_images/954a2c74f4bbfebf42e38cf9fa40f8fc01d4acd1cd324bc1ee2a1e3234d3c189.png

As mentioned before, we can write quantitative measurements on top of each element, like its area.

# Visualization
fig, axs = plt.subplots(1, 1)
cle.imshow(blobs, continue_drawing=True, plot=axs)
cle.imshow(cle.reduce_labels_to_label_edges(labeled_blobs), labels=True, plot=axs, continue_drawing=True, alpha=0.7)

# Plot label number over each element (iterate over each element)
for element in regionprops:
    # Get element centroid (x, y)
    element_centroid = (element.centroid[1]-8, element.centroid[0]+5)
    
    # Get element label and convert it to string
    element_area = str(element.area)
    
    # Plot label number at the coordinates of that element centroid
    axs.annotate(text = str(element_area) + " px", xy = element_centroid, fontsize = 7, color = 'white')
../_images/f5b0ecfdb871be034dc6a1c42ed6a18ef252a37035ecc66ca9b734db27bc74a8.png