I'm using the regionprops
function from the scikit-imag
e (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
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With