Automating measurement and renaming of selections in ROI Manager

Tags: #<Tag:0x00007fb87d89e940> #<Tag:0x00007fb87d89e7b0> #<Tag:0x00007fb87d89e5f8>


Hello there!

I have very little experience with Image J and have tried to solve my coding issues by looking online and in this forum. I have made some progress but I am stuck and don’t know whether what I am trying to do is even feasible. Alas, I am hoping someone here can nudge me in the right direction or let me know what I am doing wrong. Any input would be massively helpful :slight_smile:

So, I have a number of images to analyse, which have leaves attached to them, as below:

NB: I am using a .tif file but it wouldn’t upload so I have attached a .jpg version instead.

I first transformed the image into 8-bit and made it binary, so that it would be easier to select and measure each sample. I am measuring the length, width and surface area of each leaf, which I have done by fitting an ellipse and making it centroid. Each row is a different letter (A-E), and each column is a subheading (i-iii). So the first row is A-i, A-ii, A-ii, the second row is B-i, B-ii, B-iii and so on.

I first select each leaf with the wand, then add it to the ROI Manager and select it in the list to rename. I update and repeat this for all the leaves. I was recording a macro of these steps and figured I could simplify it since I’m repeating the same tasks. This is the code I ended up with after doing these steps manually:

setOption("BlackBackground", false);
run("Make Binary");

run("Set Measurements...", "area mean min centroid fit display add redirect=None decimal=3");
run("ROI Manager...");

doWand(666, 462);
roiManager("Select", 0);
roiManager("Rename", "A-i");

doWand(1320, 558);
roiManager("Select", 1);
roiManager("Rename", "A-ii");

doWand(1986, 492);
roiManager("Select", 2);
roiManager("Rename", "A-iii");

This code works fine, but I have over 20 images, each with 15 leaves to measure, so I decided to try and automate the process using loops in the default ImageJ Macros (IJ1 Macro language). First, I selected all the leaves individually to get the coordinates, and then I made them into an array. I couldn’t figure out how to keep the coordinates as “(x,y)”, since the array and the doWand function would only accept comma delimited numbers:

CORD = newArray (666, 462, 1320, 558, 1986, 492,  666, 1086, 1326, 1068, 1992, 1044,  684, 1698, 1332, 1710, 2022, 1728,  690, 2292, 1350, 2340, 2058, 2274,  690, 2844, 1320, 2916, 2088, 2928)
for (m = 0; m < CORD.length; m++)

I have some very limited experience using python, so I was trying to get the doWand command to select coordinates from the array based on their position. So the first coordinate would be (CORD[m], CORD[m++]), since it is the first two values. I put this part into a loop which would select, rename and update in ROI Manager. So in theory when n=0, m=0 and m=1 for the first leaf, then for the second it would be n=1, m=1 and m=2 (Where “n” is the position of the selected leaf in ROI Manager). The doWand isn’t recognising what I was trying to do, and I wonder maybe if this line requires a nested loop defining the start values of m and its progression?

for (n=0; n<15; n++) {
	doWand(CORD[n], CORD[n++]);
	roiManager("Select", [n]);
	roiManager("Rename", [a, b]);
		if (n == 0, 1, 2), a = "A";
		else if (n == 3, 4, 5), a = "B";
		else if (n == 6, 7, 8), a = "C";
		else if (n == 9, 10, 11), a = "D";
		else if (n == 12, 13, 14), a = "E";

		if (n == 0, 3, 6, 9, 12), b = "-i";
		else if (n == 1, 4, 7, 10, 13), b = "-ii";
		else (n == 2, 5, 8, 11, 14), b = "-iii";


Within ROI Manager, I wanted to generalise the “Select” function so that it would just be “n”. However the macro isn’t recognising that as a valid input and keeps generating error. I don’t know if it would be better to use a different coding language, or to find some way to fix this :\

In terms of naming each leaf, I wanted to try to create a concatenated string that would output a name based on the “n” value, and separating this into the row and column components. As in the image, the first row is “A”, the second is “B”, and so on all the way to “E”. I identified the corresponding “n” values, but I couldn’t understand how to make it so that “n” satisfied any of the numbers in the bracket (I looked up Boolean OR, but again, I’m not sure if that’s even remotely correct). In the image, all the leaves in a vertical column have the same roman numeral suffix; the first leaf in each row should be “-i”, the middle column is “-ii”, and the last column is “-iii”. I tried to make it so the “a” represented the rows and “b” represented the columns, hence the separate if statements.

I am aware that the syntax is very wrong, but I just tried to break down what I wanted the macro to do before attempting to code it. Since I failed that, I have tried to explain my logic in the hopes that someone can help me figure out what to do. I don’t know if I have tried to over complicate what I want to do, but any advice or help with the code would be greatly appreciated.



Dear @mlk,

sorry that your post has been sitting here for so long. I will leave some thoughts here, that might be helpful to you:

You could also have two arrays:

xCoordinates = newArray(666, 1320, ...);
yCoordinates = newArray(462, 558, ...);

That way, in your for loop you can do

doWand(xCoordinates[n], yCoordinates[n]);

which seems easier to handle.

roiManager("Select", n) expects n to be a number, so you need to drop the brackets (which are syntactically wrong anyway).

That is very good thinking!

The following snippet will store different characters in a variable called a.

if (n <= 2) a = "A"; // (n == 0, 1, 2)
else if (n <= 5) a = "B"; // (n == 3, 4, 5)
else if (n <= 8) a = "C"; // (n == 6, 7, 8)
else if (n <= 11) a = "D"; // (n == 9, 10, 11)
else if (n <= 14) a = "E"; // (n == 12, 13, 14)

The second part could be solved mathematically by looking at the remainder of a division (aka modulo):

if (n%3==0) b = "-i"; // (n == 0, 3, 6, 9, 12)
else if (n%3==1) b = "-ii"; // (n == 1, 4, 7, 10, 13)
else (n%3==2) b = "-iii"; // (n == 2, 5, 8, 11, 14)

And the final step. You can concatenate strings (glue them together) with the + operator:

roiManager("Rename", a+b);

I hope that helps,


Thank you so much for the corrections! It works perfectly now :smile: :raised_hands: #lifesaver