# How to measure standard deviation of intensities with scikit-image regionprops

Hi all,

I’m trying to measure the standard deviation of labelled regions using scikit-image. The documentation unfortunately doesn’t contain the terms “standard deviation” and “variance” and google is also not very helpful. Thus, I’m asking here.

Assume this is our image:

``````1 2 3
4 5 6
7 8 9
``````

Depending on if you use the equation for a population or a sample of pixels, you can determine a standard deviation of 2.58 or 2.74, respectively. `numpy.std` returns the first. So far, so good. But how to do this for multiple labels using skimage.measure.regionprops ? The variance is also known as the second moment and thus, I would expect to find the variance of my image in its moments.

Here is some python code for printing out moments. Again my question: How can I retrieve the standard deviation from these?

``````import numpy as np

image = np.asarray([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])

labels = np.asarray([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
])

print("numpy standard deviation", np.std(image))
print("numpy variance", np.var(image))

from skimage.measure import regionprops
stats = regionprops(labels, intensity_image=image)

print(stats[0].moments)
print(stats[0].moments_central)
print(stats[0].moments_normalized)
``````

Output:

``````numpy standard deviation 2.581988897471611
numpy variance 6.666666666666667
[[ 9.  9. 15. 27.]
[ 9.  9. 15. 27.]
[15. 15. 25. 45.]
[27. 27. 45. 81.]]
[[9. 0. 6. 0.]
[0. 0. 0. 0.]
[6. 0. 4. 0.]
[0. 0. 0. 0.]]
[[       nan        nan 0.07407407 0.        ]
[       nan 0.         0.         0.        ]
[0.07407407 0.         0.00548697 0.        ]
[0.         0.         0.         0.        ]]
``````

Thanks for your help and Merry Christmas btw.!

Cheers,
Robert

1 Like

Hello Robert!

The moments are not of the pixel intensities but rather the image moments, which are defined in terms of image coordinates. (They can also be a “convolution” of image coordinates and image intensities, and those are available under the `weighted_moments*` properties.)

So we don’t actually have an image variance, but thanks to @VolkerH, as of 0.18 we now have the `extra_properties=` parameter to `regionprops`, so you can measure whatever you can dream of!

``````import numpy as np
from skimage import measure

image = np.arange(1, 10).reshape((3, 3))
labels = np.ones_like(image, dtype=int)

# arguments must be in the specified order, matching regionprops
def image_stdev(region, intensities):
# note the ddof arg to get the sample var if you so desire!
return np.std(intensities[region], ddof=1)

props = measure.regionprops(
labels, image, extra_properties=[image_stdev]
)

print(props[0].image_stdev)
``````

Output:

``````2.7386127875258306
``````

Merry Christmas!

3 Likes

Fantastic! Thanks @jni for the instant support. I hope you were wearing a red hat while typing the solution

1 Like