In what order does skimage.measure.regionprops label the objects?

I am trying to measure the area of objects in images like this:


The objects are aligned next to each other, and i need to know to which object each measurement belongs to, in the image. I use these lines of codes:

from skimage import measure, io, img_as_ubyte
from skimage.color import label2rgb, rgb2gray
from skimage.filters import threshold_otsu
from skimage.segmentation import clear_border

wb = img_as_ubyte(rgb2gray(io.imread("myimage")))
scale = 0.6
threshold = threshold_otsu(wb)
thresh_img = wb < threshold

edge_touching_removed = clear_border(thresh_img)
label_image = measure.label(edge_touching_removed, connectivity=wb.ndim)
image_label_overlay = label2rgb(label_image, image = wb)

all_props = measure.regionprops(label_image, wb)
for prop in all_props:
    print('Label: {} Area: {}'.format(prop.label, prop.area))

The problem is i do not know in what order skimage.measure.regionprops labels the object. Is it left to right? right to left or some random order? I checked the documentation for it and it did not help. Does anyone know anything about this? Is there any way to measure the are of objects in images at all or is it some random order created by the machine?


Hi Anderson, In regionprops, you can include “bbox” or “centroid” to give you an idea of order or location of the object of interest.

1 Like

Does not change anything.

regionprops doesn’t order the objects. You provide a label image to regionprops where each label uniquely identifies the object. You should pretty much always measure the property label with your objects. You can visualize the image returned by measure.label using a tool such as matplotlib or napari to see which label corresponds to which object. I don’t know whether measure.label gives any guarantees about the order in which objects are labeled, so even if the current implementation gives a certain ordering you should not rely on having the same ordering in future versions. If you need a particular order for whatever reason you could think of implementing your own label function.

And of course you can take up the advice of @rjesud and also measure the locations of the objects. Given the labels and location you can then order the measurements however you like, e.g. increasing x coordinate etc.

1 Like

For a small number of objects you could just check it manually:

import numpy as np
import matplotlib.pyplot as plt

 for lbl in np.unique(label_image):
     # 0 would always be background
     plt.imshow(label_image == lbl)

For a big number of objects, as rjesud mentioned, you can extract the bounding box or the centroid (center of mass) of each object and use this information to order your objects by axis/axes

1 Like