 Hi everyone. I’m analysing a few images and I need to find a way of measuring the radius of a polygon ROI. I want to find the distance from centroid to edge of the polygon at 0, 10, 20, 30, …, 360 degrees. Is there a way to write a macro for this?
Thanks for any help.

Hi and welcome.
The problem you are posing is somewhat incomplete. Imagine a thick “C” shaped polygon. The centre of mass is most likely outside the ROI, so what would be a “radius” at various angles?
Can you guarantee that the polygons are convex?
If so what you are after is the set of Feret diameters at certain angles. ImageJ particle analyzer returns the largest one (and I think the shortest one).

While I do not remember a macro to do exactly this, It should be possible with programming in any of the various scripts supported by IJ.
You can get the centre of mass already with the particle analyzer and you should be able to extract the polygon perimeter coordinates and “walk” around it, keeping a note of the angle with regard to an arbitrary start line. That is quite a lot of work if you are not familiar with programming. Also there is no guarantee that for a given angle there is only one perimeter point (think of a very convoluted perimeter).

Another issue, think of a pointy star and a set of angles that do not coincide with the furthest points from the centre of mass: you may get an incomplete sense of the shape for that ROI. To minimise this it would be necessary to take many angles, which kind of defeats the point of getting a small set of parameters to describe shape.

Maybe before embarking into a programming task to implement this and then test and debug, you could look at other shape analysis parameters that might just be enough for your problem.
Or you may get lucky and somebody has already coded it.

Hi Gabriel
Thanks for your help. The ROIs are roughly circular/elliptical so there will only be one intersection point. I’m essentially trying to do a centroid distance function, so the final outcome would be a graph of the shape profile. But to standardise the approach it would be good to have data for same angles for each image.

I want to be able to draw a line from ROI centroid to boundary of ROI at X degrees, and then find the length of that line (or the coordinates of the intersection). If I can do that I can adjust the angle of the line to get the data I need.

I want to do something like this study, except I would have to draw the area myself rather than using a ‘find edge’ tool.

https://iopscience.iop.org/article/10.1088/1755-1315/31/1/012002/pdf

Hi, Herbie G. saw your post and has kindly sent me the macro below which works for convex and “moderately concave” polygons. He said it was fine to post it here.
All credits to Herbie.

``````/* ImageJ-macro "polygonRays" (Herbie G., 12. July 2019)
===================================
Draws and measures rays from the center of a polygon to
its edges at regular angle increments, provided the center
lies within the polygon and all rays reach the edges from
inside the polygon (moderate concavity). Rays start from
pointing to the left and their angles increase clockwise.
=================================*/
inc=10; // angle increment
requires( "1.52p" );
Table.reset("Results");
c=PI/180;
nme=split(getTitle(), ".");
List.setMeasurements;
cX=List.getValue("X");
cY=List.getValue("Y");
getSelectionCoordinates(x, y);
run("Select None");
n=x.length;
a=newArray(n);
for ( i=0; i<n; i++ ) a[i]=180*(1+atan2(y[i]-cY, x[i]-cX) / PI);
// order poly-corners
Table.create("temp");
Table.setColumn("Angle", a);
Table.setColumn("X", x);
Table.setColumn("Y", y);
Table.sort("Angle");
a=Table.getColumn("Angle");
x=Table.getColumn("X");
y=Table.getColumn("Y");
close("temp");
//
for ( j=0; j<360; j+=inc ) {
for ( i=0; i<n; i++ ) {
if (i<n-1) {
if ( a[i]<=j && j<a[i+1] ) d=distance(j*c,x[i],y[i],x[i+1],y[i+1],cX,cY);
} else {
if ( a[i]<=j || j<a ) d=distance(j*c,x[i],y[i],x,y,cX,cY);
}
}
setResult("Label", nResults, nme);
setResult("Angle", nResults-1, j);
setResult("Length", nResults-1, d);
}
updateResults();
selectWindow("Results");
Plot.create(nme, "Degree", "Length", Table.getColumn("Angle"), Table.getColumn("Length"));
Plot.show;
exit();
function distance(phi,x1,y1,x2,y2,x3,y3) {
// edge line
dn1=x2-x1;
s1=(y2-y1) / dn1;
o1=y1-s1*x1;
// ray line
s2=tan(phi);
o2=y3-s2*x3;
// ray
if (dn1!=0) {
x4=(o1-o2) / (s2-s1);
y4=s1*x4+o1;
} else {
x4=x1;
y4=s2*x4+o2;
}
makeLine(x3, y3, x4, y4);