Perimeter value - perimeter of convex hull is larger than perimeter of sample

Hi all,

I’ve been trying to use the Convexity and Solidarity macro ( ) on a series of segmented (binary) images of many particles. However when I look at the convexity values they are frequently larger than 1, which should be impossible given that the perimeter of a convex hull should always be smaller than the perimeter of the object.

I tested the macro using a couple of self drawn shapes, including a 2 pixel rectangle and a 4 pixel square. The areas come out correctly for both the shape and its convex hull, however the perimeter of the 2 pixel square (which should be 6) comes out as 4.24 and the perimeter of the square (which should be 8) as 5.65. The perimeters of the convex hull are correct which is giving me convexity values greater than 1.

Why is the perimeter function of analyze particles giving me smaller values than expected and how can I get the true values?


Please post an example to understand what is going on.
Also be aware that there are several ways of measuring areas and perimeters in the discrete domain.

For example using this method for encoding profiles (chain codes):
Freeman H, “Computer Processing of Line-Drawing Images” ACM Computing Surveys, vol. 6, no. 1, pp. 57–97, 1974.
The perimeter of a 2x2 pixels ‘square’ is 4, not 8 and its area is 1.
A 2x1 pixel ‘rectangle’ has no area, but it is a line of length 1.
It also matters if you use 8 or 4 neighbour connection.

Here is an example:
The image is 100 pixel by 100 pixel, with squares of areas of 1, 4, 16, and 36 pixels respectively. Running the solidity and convexity script (results shown below the image) gives me perimeters for the objects that are smaller than for the convex hull. The perimeters for the convex hull are what I expect them to be for the object. For squares the perimeter of the convex hull should equal the perimeter of the object.

Why is the perimeter for the object being calculated differently than for the convex hull and why is it smaller?

Example_1.bmp (10.8 KB)


1 Like

As mentioned before there are various ways to encode a discrete perimeter, some methods do a correction that on average has smaller errors than others, so this is perhaps one such case.

The Freeman’s chain code (I also gave you a reference) that the Particles8 plugin uses, returns on your image the following:
Perimeters: 0, 4, 12 and 20
Areas: 0, 1, 9 and 25
Pixels: 1, 4, 16 and 36
Solidity: -1, 1, 1, 1
(-1 means that is not computable as it is not a region, but a single pixel, i.e. a point with no perimeter or area).
Note that in this approach for encoding discrete regions, area is not the same as “number of pixels” but the area inside the perimeter encoded by the Freeman’s algorithm.

The Particles8 plugin is included in the Morphology update site in Fiji and also in my page.

Note 1 : I just discovered a bug in IJ that for some reason treats differently BMP and TIFF images when manipulating them as 1 slice stack. I already reported this to Wayne but in the mean time please use TIF format if you want to run that plugin.

Note 2: you are using an Inverted LUT, which means that when you see black, actually it is white and vice versa. This causes endless confusion and perhaps you should avoid using those, specially with plugins that expect a specific type of image encoding (for instance white regions on a black background).


HI noahjp,

I too have been struggling with perimeter in imageJ, but in the context of circularity. Here’s some details about what’s going on.

The TLDR is that the perimeter reported in imageJ is for a different shape and the algorithm used may not be the best.

As @gabriel mentioned, it is difficult to even define a perimeter is for a digitised shape and there are plugins that do a better job.



The naive approach

The simplest approach for calculating the perimeter of a traced Roi is to add up the sides of the pixels exposed to outside. This leads to some confusing results.

In mathematical terms, this is because this is equivalent to using the ‘Taxicab distance’ or \ell_1-norm to measure distances.

Using this approach leads to a number of problems. For example, these two shapes both have a perimeter 44.


It also means that the perimeter is not invariant to rotations. In this example a line of length 20 and width 1 is rotated and the \ell_1-perimeter calculated:

Fixing the issue

Approaches to correct the deficiencies of the \ell_1-perimeter can be seen as building in more common Euclidean or \ell_2-norm. In the case of the diagonal line, using the \ell_2-norm a single pixel would contribute \sqrt{2} to the perimeter rather than 2.

Another way to say this is calculate the perimeter of digitised shapes we need to ‘cut corners’ rather than use the taxi-cab metric which sticks to the pixel grid.

The approach in imageJ

The code currently calculates the perimeter by first calculating the taxi-cab perimeter, then replacing some of the corner pixels with a diagonal:

Returns the perimeter length of ROIs created using the wand tool
and the particle analyzer. The algorithm counts pixels in straight edges
as 1 and pixels in corners as sqrt(2).It does this by calculating the total length of the ROI boundary and subtracting
2-sqrt(2) for each non-adjacent corner.

It can be thought as doing some thing like the following:


The code itself is more complicated and often the output can’t be interpreted in terms of shapes like above. To visualise what is happening I modified the code to mark which edges get marked as ‘non-adjacent’. In this case it marks 6 edges as ‘non-adjacent’ corners and calculates the perimeter as 6+3\sqrt{2}.


The edges that get marked ‘non-adjacent’ depend on the orientation of the shape and which point it starts at. This leads to some strange results, for example, this shape has a different perimeter depending on the orientation

Sequence of squares

For the sequence squares the corners cut off can easily visualised. The perimeters are smaller than convex hull because they are for a different shape!


Area perim
1 2\sqrt{2}
4 4+4\sqrt{2}
9 8+4\sqrt{2}
16 16+4\sqrt{2}

Thank you Chris and Gabriel,

That clarifies things greatly. The particles8 plugin from @gabriel indeed calculates convexity better than using the Convexity/Solidity macro, and solves the changing perimeter with rotation issue.

Thanks so much for explaining in such detail how imageJ calculates perimeter,


By the way, the bug that I reported above (TIF and BMP filed behaving differently when treated as a 1 slice stack) has bee resolved by Wayne in the latest build. Thanks Wayne!

1 Like

14 posts were split to a new topic: Convex hull perimeter usage