Search code examples
pythonfilteringscikit-imagemasking

Filter regions using skimage regionprops and create a mask with filtered components


I have generated a mask through Otsu's Method and now I have to eliminate certain closed regions from it that do not satisfy area or eccentricity conditions. I label the mask with skimage.measure.label function and then apply skimage.measure.regionprops to it to get information about the area and eccentricity of the regions. The code is the following:

lab_img = label(mask)
regions = regionprops(lab_img)

for region in regions:
    if (condition):
        # Remove this region

# final_mask = mask (but without the discarded regions)

Does anyone know an efficient way to do this? Thank you!


Solution

  • Here's one way to get what you want. The critical function is map_array, which lets you remap the values in an array based on input and output values, like with a Python dictionary. So you could create a table of properties using regionprops_table, then use NumPy to filter those columns quickly, and finally, remap using the labels column. Here's an example:

    from skimage import measure, util
    
    ...
    
    lab_image = measure.label(mask)
    
    # table is a dictionary mapping column names to data columns
    # (NumPy arrays)
    table = regionprops_table(
        lab_image,
        properties=('label', 'area', 'eccentricity'),
    )
    condition = (table['area'] > 10) & (table['eccentricity'] < 0.5)
    
    # zero out labels not meeting condition
    input_labels = table['label']
    output_labels = input_labels * condition
    
    filtered_lab_image = util.map_array(
        lab_image, input_labels, output_labels
    )