52 views (last 30 days)

Show older comments

Hi,

I am trying to calculate the Circularity using regionprops (based formula: (Perimeter^2)/(4 Pi Area)). The Problem ist that the Circularity is more than 1 for some objects. Are there any other way's for a better calculation?

John D'Errico
on 10 Jul 2020

Edited: John D'Errico
on 10 Jul 2020

It would not be unusual for that measure to exceeds 1. For example, given a circle, we would have a perimeter of 2*pi*r. So permieter squared would be 4*pi^2*r^2. And the area of a curcle is pi*r^2. So that measure would in theory be 1 for a circle.

And people talk about how the circle has the largest area for a given perimeter. I fact though, that is incorrect. A circle has the largest possible area of all convex regions. But suppose the region is not convex?

For example, consider a circle, but then super-impose a rapidly varying sinusoidal oscillation. Small amplitude, but high frequency. Essentially think of this as creating a fuzzy circle. The perimeter will increase, yet the area stays almost unchanged.

Just for kicks. I'll create such an object, then compute both the perimeter and the area.

F = 100; % frequency of the sinusoidal fuzz

N = 2000;

theta = linspace(0,2*pi,N);

R = 1; % Nominal radius of the circle

A = 0.05; % fuzz amplitude

Xc = (R+A*sin(F*theta)).*cos(theta);

Yc = (R+A*sin(F*theta)).*sin(theta);

plot(Xc,Yc,'-')

What is the arc length of this perimeter curve?

I have a function on the file exchange that can compute the arclength of such a curve.

fuzzyperim = arclength(Xc,Yc,'spline')

fuzzyperim =

21.395

If you don't trust my code, or don't wish to download it from the file exchange, this will give a decent estimate of the perimeter too:

sum(sqrt(diff(Xc).^2 + diff(Yc).^2))

ans =

21.317

If it were really, truly a circle, the perimeter arclength would have been

2*pi*R

ans =

6.2832

What is the actual area of that region? Were it a circle, we would get:

pi*R^2

ans =

3.1416

So, for a truly circular region, we would have:

(2*pi*R)^2/(4*pi*pi*R^2)

ans =

1

What is the area of the region? Numerical integration in polar coordinates will suffice. The area is just the integral of r*r*dtheta. (Don't forget that extra r, since we are working in polar coordinates.)

radfun = @(theta) R+A*sin(F*theta);

fuzzyarea = integral(@(theta) radfun(theta).^2,0,2*pi)

fuzzyarea =

6.291

As expected, the area is almost unchanged, whereas the perimeter is significantly larger than the circle would have been. So how good is this measure of cicularity?

fuzzyperim^2/(4*pi*fuzzyarea)

ans =

5.7903

As it turns out, not very good. For something that you thought would never be larger than 1, the ratio is now almost 6. Really, it applies only for nice well behaved regions. Convexity is actually rather important. If the region is at all fuzzy or not convex, then you need to be careful.

Is there a better measure of circularity? That is a good question. You might compute the perimeter and area of the convex hull of the regions, then use those numbers to compute circularity.

Image Analyst
on 10 Jul 2020

Edited: Image Analyst
on 10 Jul 2020

With that definition of circularity, which is the one I use, of course it will be more than 1. THeoretically it would be 1 for a circle and greater than 1 for any non-circular shape. So that's normal. But what is unexpected is that the value can be less than 1 for some shapes. When this happens it's because of the way perimeter and area are measured for digitized shapes, and it's worse the smaller the shape is (the more the quantization error is relative to the number of pixels.)

For example, what is the distance between the endpoint 1 pixels in this shape

0 1 1 1 0

From the left 1 to the right 1, what is the distance? Is it 3 because it's 3 pixels long? Or is it 2 because if you go from the center of the left-most pixel to the center of the right-most pixel, that's a distance of 2?

What is the area and perimeter of this shape

0 0 0 0 0

0 1 1 1 0

0 1 1 1 0

0 0 0 0 0

Is the area 6? Or is the area 2? Arguments can be made both ways and it could depend on the optics or physics of the situation that gave rise to the image.

What is the perimeter of this shape:

0 0 0 0 0

0 0 1 1 0

0 1 1 1 0

0 0 0 0 0

Is it 5? Or is it 4 + sqrt(2)? When you go diagonally do you consider that a distance of 1 pixel because it's the next pixel over? Or do you consider it sqrt(2) because it's the hypoteneuse of a square that is 1 unit on a side?

Well what does regionprops() and bwarea() say about the area, etc.?

mask = [...

0 0 0 0 0

0 0 1 1 0

0 1 1 1 0

0 0 0 0 0]

props = regionprops(mask, 'Area', 'Perimeter');

area = bwarea(mask);

circularity = props.Perimeter / (4 * pi * props.Area);

fprintf(' bwarea() says the Area = %f\nregionprops() says the Area = %f\nPerimeter = %f\nCircularity = %f\n',...

area, props.Area, props.Perimeter, circularity);

mask =

0 0 0 0 0

0 0 1 1 0

0 1 1 1 0

0 0 0 0 0

bwarea() says the Area = 5.125000

regionprops() says the Area = 5.000000

Perimeter = 4.962000

Circularity = 0.078973

Huh -- how about that?

By the way, there are other definitions of circularity. If you want circularities to go from 0 to 1, just invert your formula so it's (4*pi*Area)/(perimeter^2).

And there are even more definitions: Wikipedia Roundness

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!