Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add extra properties to regionprops in skimage

I'm using the regionprops function from the scikit-image (or skimage) package to compute region features of a segmented image using the SLIC superpixel algorithm from the same package.

I need additional features than those computed in the fucntion, mainly : standrad deviation, skewness, kurtosis.

I modified the source code of _regionprops.py using the other features as template in order to include those properties :

    @property
    def sd_intensity(self):
        return np.std(self.intensity_image[self.image])

    @property
    def skew_intensity(self):
        return skew(self.intensity_image[self.image])

I know this is bad practice, and not a long term solution because my code won't be able to run on another machine or if i update skimage.

I discovered that the function skimage.measure.regionprops() has a extra_properties=None parameter, which according to the doc:

Add extra property computation functions that are not included with skimage.

My question is : Can I get a working example with np.std ? I don't really know how to use this parameter.

Thanks

like image 323
Benson_YoureFired Avatar asked Dec 17 '22 12:12

Benson_YoureFired


2 Answers

extra_properties just takes a list of functions with region mask and intensity image as arguments. Here's a quick example:

from skimage import data, util
from skimage.measure import label, regionprops
import numpy as np
img = util.img_as_ubyte(data.coins()) > 110
label_img = label(img, connectivity=img.ndim)

def sd_intensity(regionmask, intensity_image):
        return np.std(intensity_image[regionmask])

def skew_intensity(regionmask, intensity_image):
        return skew(intensity_image[regionmask])
    
props = regionprops(label_img, intensity_image=img,
                    extra_properties=(sd_intensity, skew_intensity))

You can now access your extra properties using your function names

props[0].sd_intensity
>>> 0.4847985617008998

EDIT 08/28/2021, updated the example to actually compute region local statistics as pointed out by @CrisLuengo and @JDWarner (thank you guys)

like image 66
filippo Avatar answered Dec 30 '22 20:12

filippo


The above accepted answer by filippo is (edit: was - now corrected; original post follows) subtly incorrect in a dangerous way. The statistics returned with that answer are applied to the intensities of the entire bounding box, not the masked and labeled subregion! The extended functions passed need to use regionmask to slice the intensity image. Complete corrected example:

import numpy as np
from scipy.stats import skew
from skimage import data, util
from skimage.measure import label, regionprops

img = util.img_as_ubyte(data.coins()) > 110
label_img = label(img, connectivity=img.ndim)

def sd_intensity(regionmask, intensity_image):
        return np.std(intensity_image[regionmask])  # Note slicing

def skew_intensity(regionmask, intensity_image):
        return skew(intensity_image[regionmask])   # Note slicing
    
props = regionprops(label_img, intensity_image=img,
                    extra_properties=(sd_intensity, skew_intensity))

This will properly produce local statistics for just the labeled regions of the intensity image.

I do not yet have sufficient "reputation" to comment on that answer so submitting as a separate answer since this is an important distinction.

like image 31
JDWarner Avatar answered Dec 30 '22 21:12

JDWarner