Tom
Tom

Reputation: 15

How do I filter by area or eccentricity using skimage.measure.regionprops on a binary image in Python

I have a binary image of a road surface and I am trying to isolate the pothole only. Using skimage.measure.regionprops and skimage.measure.label I can produce a table of properties for different labels within the image.

How do I then filter using those values? - for instance using area or axis length or eccentricity to turn off certain labels. Input, labled Image and properties table

using python 3

Upvotes: 0

Views: 2611

Answers (1)

Juan
Juan

Reputation: 5768

I would use pandas together with skimage.measure.regionprops_table to get what you want:

import pandas as pd
import imageio as iio
from skimage.measure import regionprops_table, label

image = np.asarray(iio.imread('path/to/image.png'))
labeled = label(image > 0)  # ensure input is binary
data = regionprops_table(
        labeled,
        properties=('label', 'eccentricity'),
        )
table = pd.DataFrame(data)
table_sorted_by_ecc = table.sort_values(
        by='eccentricity', ascending=False
        )

# print e.g. the 10 most eccentric labels
print(table_sorted.iloc[:10])

If you then want to e.g. produce the label image with only the most eccentric label, you can do:

eccentric_label = table['labels'].iloc[np.argmax(table['eccentricity'])]
labeled_ecc = np.where(labeled == eccentric_label, eccentric_label, 0)

You can also do more sophisticated things, e.g. make a label image with only labels above a certain eccentricity. Below, we use NumPy elementwise multiplication to produce an array that is the original label if that label has high eccentricity, or 0 otherwise. We then use the skimage.util.map_array function to map the original labels to either themselves or 0, again, depending on the eccentricity.

from skimage.util import map_array

ecc_threshold = 0.3
eccentric_labels = table['labels'] * (table['eccentricity'] > ecc_threshold)
new_labels = map_array(
        labeled,
        np.asarray(table['labels']),
        np.asarray(eccentric_labels),
        )

Upvotes: 3

Related Questions