Quantitative image analysis#

After segmenting and labeling objects in an image, we can measure properties of these objects.

See also

Before we can do measurements, we need an image and a corresponding label_image. Therefore, we recapitulate filtering, thresholding and labeling:

from skimage.io import imread
from skimage import filters
from skimage import measure
import pandas as pd
import numpy as np
import stackview
# load image
image = imread("data/blobs.tif")

# denoising
blurred_image = filters.gaussian(image, sigma=1)

# binarization
threshold = filters.threshold_otsu(blurred_image)
thresholded_image = blurred_image >= threshold

# labeling
label_image = measure.label(thresholded_image)

# visualization
stackview.insight(label_image)
shape(254, 256)
dtypeint32
size254.0 kB
min0
max62
n labels62

Measurements / region properties#

To read out properties from regions, we use the regionprops_table function, which directly returns a dictionary that can be converted to a pandas DataFrame:

# analyse objects using regionprops_table
properties = ['label', 'area', 'mean_intensity', 'major_axis_length', 'minor_axis_length']

measurements = measure.regionprops_table(label_image, intensity_image=image, properties=properties)

df = pd.DataFrame(measurements)
df.head()
label area mean_intensity major_axis_length minor_axis_length
0 1 429.0 191.440559 34.779230 16.654732
1 2 183.0 179.846995 20.950530 11.755645
2 3 658.0 205.604863 30.198484 28.282790
3 4 433.0 217.515012 24.508791 23.079220
4 5 472.0 213.033898 31.084766 19.681190

The result is already a dictionary of arrays, which can directly be used as a pandas DataFrame. The properties available are listed in the documentation of the measure.regionprops function.

We can add custom columns, for example the aspect_ratio:

# add aspect_ratio column
df['aspect_ratio'] = df['major_axis_length'] / df['minor_axis_length']

df.head()
label area mean_intensity major_axis_length minor_axis_length aspect_ratio
0 1 429.0 191.440559 34.779230 16.654732 2.088249
1 2 183.0 179.846995 20.950530 11.755645 1.782168
2 3 658.0 205.604863 30.198484 28.282790 1.067734
3 4 433.0 217.515012 24.508791 23.079220 1.061942
4 5 472.0 213.033898 31.084766 19.681190 1.579415

Those dataframes can be saved to disk conveniently:

df.to_csv("blobs_analysis.csv")

Furthermore, one can measure properties from our df table using numpy. For example the mean area:

# measure mean area
np.mean(df['area'])
np.float64(355.3709677419355)

Exercises#

Analyse the loaded blobs image.

  • How many objects are in it?

  • How large is the largest object?

  • What are mean and standard deviation of the image?

  • What are mean and standard deviation of the area of the segmented objects?