## Steve on Image Processing and MATLABConcepts, algorithms & MATLAB

### This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the English version of the page.

# Customizing REGIONPROPS With Your Own Measurements12

Posted by Steve Eddins,

I saw a presentation last month that mentioned a user request to have the ability to customize regionprops. That is, a user wanted to be able to add their own measurement to regionprops.

Today, I'll show you how to do this yourself.

First, here's a brief recap on what regionprops does. The function computes measurements of image regions. Some of these measurements are based purely on a region's shape, while others incorporate pixel values within the regions. Here's an example using the coins.png sample image.

I = imread('coins.png');
imshow(I)


Let's convert this image to binary, using adaptive thresholding, filling holes, and removing small "noise" pixels.

bw = imbinarize(I,'adaptive');
bw = imfill(bw,'holes');
bw = bwareafilt(bw,[100 Inf]);
imshow(bw)


You can count the "blobs" (object) yourself; there are 10 of them.

The simplest regionprops call, regionprops(bw) computes the Area, Centroid, and BoundingBox for each object.

s = regionprops(bw)

s =

10×1 struct array with fields:

Area
Centroid
BoundingBox



But I don't think this is the best way to call regionprops anymore. You can now tell regionprops to return the results as a table.

t = regionprops('table',bw)

t =

10×3 table

Area        Centroid        BoundingBox
____    ________________    ____________

2635    37.133    106.85    [1x4 double]
1846    56.131    49.693    [1x4 double]
2672    96.199    146.05    [1x4 double]
1839    109.97    84.848    [1x4 double]
2744    120.37    208.73    [1x4 double]
2520    148.57    34.404    [1x4 double]
2589    174.83    120.01    [1x4 double]
2518    216.81    70.649    [1x4 double]
1857    236.03    173.36    [1x4 double]
1829    265.96    102.64    [1x4 double]



The table form is a lot more convenient for many tasks. For today's topic, one especially nice thing thing about tables is how easy it is to add your own variables to the table.

To illustrate, let's add a measurement that I've seen called Roundness. One definition for roundness is:

$R = \frac{4A}{\pi L^2}$

where $A$ is the object area and $L$ is the major axis length of the best-fit ellipse for the object. Here's how to compute roundness and add it directly to the measurements returned by regionprops.

First, note that both Area and MajorAxisLength are supported by regionprops, so let's start with those.

t = regionprops('table',bw,'Area','MajorAxisLength')

t =

10×2 table

Area    MajorAxisLength
____    _______________

2635     60.08
1846    50.178
2672    59.792
1839    49.674
2744    60.374
2520     58.08
2589    58.676
2518    58.162
1857     49.77
1829    49.564



You access table variables using dot notation, like t.Area. Similarly, you can create a new table variable using dot notation and assignment, like t.MyVariable = .... So adding Roundness to the table returned by regionprops is this simple.

t.Roundness = 4 * t.Area ./ (pi * t.MajorAxisLength.^2)

t =

10×3 table

Area    MajorAxisLength    Roundness
____    _______________    _________

2635     60.08             0.92945
1846    50.178             0.93352
2672    59.792              0.9516
1839    49.674             0.94893
2744    60.374              0.9585
2520     58.08             0.95118
2589    58.676             0.95745
2518    58.162             0.94772
1857     49.77             0.95453
1829    49.564             0.94798



Let's try this computation with an image containing objects that are not quite as round.

I2 = imread('rice.png');
imshow(I2)

bw2 = imbinarize(I2,'adaptive');
bw2 = imfill(bw2,'holes');
bw2 = bwareafilt(bw2,[100 Inf]);
imshow(bw2)

t2 = regionprops('table',bw2,'Area','MajorAxisLength');
t2.Roundness = 4 * t2.Area ./ (pi * t2.MajorAxisLength.^2);

ans =

8×3 table

Area    MajorAxisLength    Roundness
____    _______________    _________

138     23.594             0.31562
120     18.152              0.4637
169     28.123             0.27207
157     23.793              0.3531
284     43.757             0.18885
200     26.259             0.36929
141     21.647             0.38311
177     29.087             0.26636



I'm a big fan of the (relatively) new histogram function in MATLAB, so let's use it to compare our roundness numbers. I will follow the advice given in the histogram reference page for normalizing multiple histograms so that they can be more easily compared. I'll set the y-axis limits to [0 1], which is appropriate for probability normalization, and I'll set the x-axis limits to [0 1], which is the range for Roundness.

h1 = histogram(t.Roundness);
hold on
h2 = histogram(t2.Roundness);
hold off
h1.Normalization = 'probability';
h2.Normalization = 'probability';
h1.BinWidth = 0.02;
h2.BinWidth = 0.02;

xlim([0 1]);
ylim([0 1]);

title('Histogram of roundness (probability normalization)')
legend('coins','rice')


There you have it. You can add your own object measurements to the output of regionprops. It's especially easy if you tell regionprops to return a table.

I'll leave you with this question, dear reader: Are there measurements you would like us to add to regionprops? I am aware of an enhancement request for the Feret diameter. What else would you like to see?

Get the MATLAB code

Published with MATLAB® R2017a

### Note

Image Analyst replied on : 1 of 12
Steve, good to share this. I often compute what I call circularity = perimeter.^2./(4*pi*area). I should also start using the table output - just too used to the old structure array (for now). The new histogram() is nice. It could be a replacement for imhist() except for cases where you want to use standard bins 0-255 and 0-65535 instead of the automatically calculated bins that histogram uses. Do you think that imhist() and histogram() could be consolidated somehow into a single histogram function? Also, MajorAxisLength is of limited usefulness because the definition (max length of an ellipse fitted to the shape) is not what people usually want, and that is the maximum Feret (caliper) diameter. And the min width would be the caliper diameter 90 degrees to the max caliper diameter. Do you think you could add this more useful measurement?
Steve Eddins replied on : 2 of 12
IA—Thanks for your feedback. I will share it with the Image Processing Toolbox development team.
Steve Eddins replied on : 3 of 12
IA—The following code using histogram produces a plot similar to imhist, except that it does not include the gray bar, and it does not do y-axis clipping:
I = imread('rice.png');
histogram(I,'BinLimits',[0 255],'BinMethod','integers')
xlim([0 255])

Steve Eddins replied on : 4 of 12
IA—I think of perimeter as a fairly noisy measurement, and it is squared in your circularity measurement. In your experience, is the circularity measure using the squared perimeter term useful?
Steve Eddins replied on : 6 of 12
IA—Regarding the pros and cons of different ways to compute orientation, Russ says: "There are a number of different [orientation] parameters that are used, including the orientation of the longest dimension in the feature (the line between the two points on the periphery that are farthest apart, also known as the maximum Feret's diameter), and the orientation of the major axis of an ellipse fitted to the feature boundary. But just as the centroid is a more robust descriptor of the feature's location than is the midpoint, the orientation defined by all the pixels in the image is often better than any of these because it is less influenced by the presence or absence of a single pixel around the periphery where accidents of acquisition or noise may make slight alterations in the boundary." The Image Processing Handbook, 2nd ed, 1995, p. 490.
luca replied on : 7 of 12
hi! I am a student and i am studying the property of osteocyte lacunae (called blob) in bovine femour. i would like to find the volume of each blob. is possible to calculate the volume of each lacunae with the function called regionprops? i used it in image 2D to obtain centroid and area of each image in 2D. if the answer is false, could you suggest another function that works for that problem? thanks a lot Luca
Pete Mc replied on : 8 of 12
Just to second what Image Analyst said ... "MajorAxisLength is of limited usefulness because the definition (max length of an ellipse fitted to the shape) is not what people usually want, and that is the maximum Feret (caliper) diameter. And the min width would be the caliper diameter 90 degrees to the max caliper diameter. Do you think you could add this more useful measurement?" I am currently unhappy with the fitted ellipse axes - am now off to research Feret diameter to see if I can implement it for my project Regards, Pete
Steve Eddins replied on : 9 of 12
Pete—Thanks for your comments. I looked into Feret diameter computations after receiving Image Analyst's comments, and I expect to blog about it soon, including some algorithm details and code.
Ross replied on : 10 of 12
Maximum feret diameter is the same as the diameter of the minimum enclosing circle. There are some functions on the file exchange to calculate this, as it requires a search (in linear time).
Guang Zeng replied on : 11 of 12
Hi Steve, Thank very much for your fantastic blogs. Could you please suggest how could I label components serially for quantification of particle growth in a image stack? I can quantify the particle quite well in each image but need to label the particles constantly across multiple images ? with help of regionprops ? Thanks very much. Guang