Sort Results by X-coordinates

When I analyze particles to measure the area of leaflets , the labels (1-9) are shown from top to bottom (as shown in figure) based on Y-coordinate.
I want the labels to be sorted from left to right based on x-coordinate.
Is it possible?
I would appreciate any help.

Thanks
Babu

Good day,

what about turning the image by 90deg?

Regards

Herbie

1 Like

Hi @brp44
I suspect the particles are numbered from top to bottom, left to right. If you want to renumber them into a grid, you could do it manually, or write a little macro.

They are numbered according to their top y-coordinate.

Herbie

If you really want them to be sorted by the x-coordinate here is a macro that does that. It expects the rois in the roi-manager and a results table that contains the corresponding measurements.

FEATURE = "BX";
REVERSE = false;

run("Set Measurements...", "area mean standard min centroid center bounding integrated limit display redirect=None decimal=3");

column = newArray(nResults);
for (i=0; i<nResults; i++) {
	column[i] = getResult(FEATURE, i);
}
positions = Array.rankPositions(column);
if (REVERSE) Array.reverse(positions);
ranks = Array.rankPositions(positions);
// Your code starts after this line
for (i=0; i<roiManager("count"); i++) {
	/* select the element number i in the roi manager*/
	roiManager("select", i);
	/* Rename the selected roi in the roi manager to its position in the sorted list, that is rename it to IJ.pad(ranks[i], 4) */
	roiManager("Rename", IJ.pad(ranks[i]+1, 4)); 
}
/* Deselect all rois in the roi-manager */
roiManager("Deselect");
/* Sort the rois in the roi-manager according to their names */
roiManager("Sort");
selectWindow("Results");
run("Close");
roiManager("Show None");
roiManager("Show All");
/* Measure the rois in the roi manager*/
roiManager("Measure");

If you want to sort them according to the grid-positions:

var _NUMBER_OF_ROWS = 3;
var _NUMBER_OF_COLUMNS =3;
var COLUMN_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");
var ROW_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");

run("Set Measurements...", "area mean standard min centroid center bounding integrated limit display redirect=None decimal=3");

for(row=0; row<_NUMBER_OF_ROWS; row++) {
		xCoords = newArray();
		for(column=0; column<_NUMBER_OF_COLUMNS; column++) {
			roiManager("select", _NUMBER_OF_COLUMNS * row + column);
			getSelectionBounds(x, y, width, height);
			xCoords = Array.concat(xCoords, x);
		}	
		rankPositions = Array.rankPositions(Array.rankPositions(xCoords));
		Array.print(xCoords);
		Array.print(rankPositions);
		for(column=0; column<_NUMBER_OF_COLUMNS; column++) {
			roiManager("select", _NUMBER_OF_COLUMNS * row + column);
			roiManager("rename", ROW_NAMES[row] + "-" + COLUMN_NAMES[rankPositions[column]]);
		}
}
roiManager("Deselect");
roiManager("Sort");
for (i=0; i<roiManager("count"); i++) {
	roiManager("select", i);
	roiManager("Rename", IJ.pad(i+1, 4)); 
}
selectWindow("Results");
run("Close");
roiManager("Show None");
roiManager("Show All");
/* Measure the rois in the roi manager*/
roiManager("Measure");
5 Likes

Hi volker,

thank you for the macro.
I am a beginner and understand very little about the code you have written.
I tried running the macro and first error was about the first line “BX”. says invalid.
When you say “it expects rois in roi-manager”, you mean I have to run my macro first and apply this macro? that did not work either.
Would you mind elaborating a little bit?

Thanks
Babu

Hi Herbie,

Thanks very much.
I did not think that way. So silly of me.

Cheers!
Babu

Hi Babu,

I just thought since I had already done this before it could be useful
to share it.

For the usage of the two macros you have to have the rois already in the
roi-manager and the corresponding measurements in the results-table. The
macro will then re-sort the rois in the roi-manager and afterwards
measure again so that the results table corresponds to the order in the
roi-manager.

I don’t think the problem is really the first line, but rather when the
variable FEATURE is used. The BX is the x-coordinate of the bounding box
of a roi. It has to be in the results table, i.e. it has to be among the
features that are measured which you can set via “Analyze>Set
Measurements”. Of course if you prefer you could use Centroid instead if
you prefer.

Yes you have to run your macro, have the rois in the roi-manager and
have pressed “measure” on the roi-manager so that the results table
corresponds to the roi-manager and have the feature you want to use for
sorting (BX for example) as a column in the results table which you can
configure via “Analyze>Set Measurements”.

By the way the macro is from our ImageJ macro programming workshop,
which you can find here:
Part 2 - Macro Programming - Application Examples 1

Also note that for the second macro (sort in grid-position order) the
rois have to be in the default order first (top-button, left-right).
This is normally the case, except if you ran the first macro (sort by a
column) before.

Please don’t hesitate to ask if things are still unclear.

Best regards,
Volker

brp44:

Good day,

a reason why the macro doesn’t work for you is that it hasn’t been formated correctly when posted to the Forum.

The posted code contains curly quotation marks that aren’t recognized as quotation marks when running the macro.

However and as suggested before, I see no need for this macro because turning the image should do the trick.

Regards

Herbie

The { } seem OK for me but the “…” in “Set Measurements…” is converted to a single ellipsis character.

Good day Gabriel,

I wrote curly quotation marks such as with:

“BX”

And yes, ellipses are also changed from three isolated points to real ellipses!

Best

Herbie

I see, I read “curly brackets” in automatic mode. Ha ha
BTW, those translated OK when I copied to the macro window. It is the two instances of “…” that got converted to the wrong character.

The macro seems to work well in a 3 x 3 matrix, however if I add one row ( 4 x 3=12 regions in total) there is an error:
Index (12) is outside the 0-11 range in line 43
Having a 4 x 4 matrix seems to work. (I am doing the ordering by the Y axis (FEATURE = “BX”; )

Hi Gabriel,
yes, you have to change the parameters

var _NUMBER_OF_ROWS = 3;
var _NUMBER_OF_COLUMNS =3;

at the top of the macro for this.

If you go beyond 11 you would need to add names to

var COLUMN_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");
var ROW_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");

as well

Best regards,
Volker

Thanks @volker, sorry perhaps I was not clear.
I did change the number of rows to 4:

var _NUMBER_OF_ROWS =  4;
var _NUMBER_OF_COLUMNS = 3;

but that generates the error.
Does the the number of columns have to be the same as the number of rows?
That is what it looks like when I run it.

@volker @anon96376101 @gabriel
Thank you all for your input and suggestions.
For now, rotating the images did the trick.
As I said I am novice to macro and will need help time and again.
I will ask you guys if I need more help.

Thanks again
Babu

Hi Babu,
you’re welcome. Just let me answer @gabriel and fix the bug in the grid-order macro :slight_smile:
You’re right there is a bug (thank you for finding it). At two places instead of

roiManager("select", _NUMBER_OF_ROWS * row + column);

it must be

roiManager("select", _NUMBER_OF_COLUMNS * row + column);

So here the corrected version:

var _NUMBER_OF_ROWS = 4;
var _NUMBER_OF_COLUMNS =3;
var COLUMN_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");
var ROW_NAMES = newArray("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K");

run("Set Measurements...", "area mean standard min centroid center bounding integrated limit display redirect=None decimal=3");

for(row=0; row<_NUMBER_OF_ROWS; row++) {
		xCoords = newArray();
		for(column=0; column<_NUMBER_OF_COLUMNS; column++) {;
			roiManager("select", ((_NUMBER_OF_COLUMNS) * row) + column);
			getSelectionBounds(x, y, width, height);
			xCoords = Array.concat(xCoords, x);
		}	
		rankPositions = Array.rankPositions(Array.rankPositions(xCoords));
		for(column=0; column<_NUMBER_OF_COLUMNS; column++) {
			roiManager("select", _NUMBER_OF_COLUMNS * row + column);
			roiManager("rename", ROW_NAMES[row] + "-" + COLUMN_NAMES[rankPositions[column]]);
		}
}
roiManager("Deselect");
roiManager("Sort");
for (i=0; i<roiManager("count"); i++) {
	roiManager("select", i);
	roiManager("Rename", IJ.pad(i+1, 4)); 
}
selectWindow("Results");
run("Close");
roiManager("Show None");
roiManager("Show All");
/* Measure the rois in the roi manager*/
roiManager("Measure");
2 Likes

Hi everyone,

I have another question.
I wanted to measure total leaf area and damaged leaf area.
For total area, I simply converted image to binary and measure it.
Now for damage area, I used color threshold [Hue(0-255), saturation (0-255) and brightness (0-76).
After selecting roi, I analyzed particles as shown in screenshot.
But the number of measured particles is very high (>6000).
Can I summarize the area for each leaf or row of leaves (X or Y coordinate)?

Thanks
Babu

Good day,

please study my contribution to a similar thread:
https://forum.image.sc/t/threshold-macro-issues-bioassay/21043/13?u=herbie

I can’t say if my approach works for your images but it may give you an idea of how the problem can be tackled in principle.

I highly recommend to do your analyses without colour-threshold.

Please post a typical raw image in the original TIF- or PNG-format.
No JPG-format though, because JPG introduces artifacts!
(Converting a JPG-compressed image to TIFF- or PNG-format doesn’t make sense.)
You may also post images as Zip-archives or make them accessible via a dropbox-like service.

Regards

Herbie

1 Like

Thanks Herbie.
Unfortunately, I saved all my images in JPEG format. I later knew that jpeg is not right format to analysis. I guess I have to use jpeg file format for now.
I look up the thread you mentioned. It is the same thing I wanted.
I used the macro created by @volker in that thread. It worked but have problem with output.
Below is the link to my image.

I also ran your macro created in that thread.
How was the lesionarea measured in that macro? Thresholding? How would I know which region was measured when lesionarea was measured? if you know what I mean. Just for confirmation as output image.
Also, in line 19 of that macro, you mention about n=9 and 9 leafs. Can n be variable? I have images with variable number of leaves but not fixed.

Cheers
Babu