 # Measuring mean of a rectangle + Printing results

Hi everyone,

I’m attempting to code a macro for the following. I have a picture with many particles that I would like to measure. After selecting them using a threshold, I’ve managed to get Fiji to print all the measurements I want using Analyze Particles. Then, I want Fiji to make a rectangular selection around each particle and measure the mean of the rectangular section. Is it possible to get Fiji to publish these mean measurements in the same table as the Analyze Particles measurements?

This is what I have so far:

``````run("Duplicate...", " ");

// Convert image to 8-bit greyscale
run("8-bit");

setAutoThreshold("Default dark");
//run("Threshold...");
// Choose regions with Greyvalue between 2 and 255 only
setThreshold(2, 255);

run("Set Measurements...", "area mean centroid center perimeter standard min fit feret's integrated redirect=None decimal=2");

// Display measurements (including Raw Integrated Density)
run("Analyze Particles...", "display");

// Create new arrays for the X and Y coordinates of all particles
locationArrayX= newArray(nResults);
locationArrayY= newArray(nResults);

for(i=0; i<nResults; i++) {
// Store X and Y coordinates in the created arrays
locationArrayX[i] = getResult("X", i);
locationArrayY[i] = getResult("Y", i);
}

//The reason I duplicate the image is because if I try to measure the mean of a rectangular selection, Fiji thinks I want to measure the means of the particles within the selection. So, I do the mean measurements in a duplicate with no thresholding applied

for (i=0; i<nResults; i++) {
// Make a rectangular selection of width and height 200, centred around the particle
makeRectangle(locationArrayX[i], locationArrayY[i], 200, 200);
//Measure the mean within the rectangular selection
getStatistics(mean);
setResult(“Background”, i, mean);
updateResults();
}
``````

This is the table I have so far– I would ideally want another column that says ‘Background’ with the measurements of the corresponding rectangular selections.

I’ve attached the image that I’m analysing here:

Any help would be much appreciated Thank you!

Jacklin & Antri

I have slightly changed your macro-code.
I suggest you go through a spreadsheet.
Then:

• Paste the above macro code to an empty macro window 'pulgin->new->macro) and run
with a image open in ImageJ.
``````waitForUser(" Have you open a spreadsheet?\nClick on OK it's finished!") ;
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
img=getImageID();
run("Duplicate...", "title=1 ");
run("Duplicate...", "title=2 ");

// Convert image to 8-bit greyscale
run("8-bit");
setBatchMode(true);
setAutoThreshold("Default dark");
//run("Threshold...");
// Choose regions with Greyvalue between 2 and 255 only
// setThreshold(2, 255);
run("Set Measurements...", "area mean centroid center perimeter standard min fit feret's integrated redirect=None decimal=2");

// Display measurements (including Raw Integrated Density)

// Create new arrays for the X and Y coordinates of all particles
locationArrayX= newArray(nResults);
locationArrayY= newArray(nResults);

for(i=0; i<nResults-1; i++) {
// Store X and Y coordinates in the created arrays
locationArrayX[i] = getResult("X", i);
locationArrayY[i] = getResult("Y", i);
}
roiManager("Reset");
selectWindow("Results");
close("2");
String.copyResults();
waitForUser(" Select your spreadsheet and paste the results \nclick on OK it's finished!") ;

//The reason I duplicate the image is because if I try to measure the mean of a rectangular selection, Fiji thinks I want to measure the means of the particles within the selection. So, I do the mean measurements in a duplicate with no thresholding applied
selectWindow("1");
run("Set Measurements...", "area mean redirect=None decimal=2");
for (i=0; i<nResults-1; i++) {
// Make a rectangular selection of width and height 200, centred around the particle
makeRectangle(locationArrayX[i], locationArrayY[i], 200, 200);

}
if (isOpen("Results")) {
selectWindow("Results");
run("Close");
}
roiManager("Measure");
selectWindow("Results");
String.copyResults();
waitForUser(" Select your spreadsheet and paste paste the results\nclick on OK it's finished!") ;
close("1");
setBatchMode(false);
exit("It's over");
``````

Please report if you don’t mind.
Greetings

1 Like

Hi Matthew!

It works great We actually have a pretty huge folder of images to process. We’ve been trying to generalise this macro such that it copies + pastes the measurements in the spreadsheet for us as it processes all the images in the folder.

But, unfortunately, we haven’t had a lot of progress– any idea how this might be possible?

Thank you kindly for all the help you’ve given us so far!

1 Like

@Jacklin_and_Antri

I think you should read this: @oburri give its macro to do what you want.

You may have to go through the arrays and concatenate:

1 Like

Hi Matthew,

Thank you for the helpful links! I’ve updated my macro to the one below:

``````setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
img=getImageID();
run("Duplicate...", "title=1 ");
run("Duplicate...", "title=2 ");

// Convert image to 8-bit greyscale
run("8-bit");
setBatchMode(true);
setAutoThreshold("Default dark");
//run("Threshold...");
// Choose regions with Greyvalue between 2 and 255 only
// setThreshold(2, 255);
run("Set Measurements...", "area mean centroid perimeter standard min feret's integrated redirect=None decimal=2");

// Display measurements (including Raw Integrated Density)

//Create new arrays for standard results
area = newArray(nResults);
mean = newArray(nResults);
perimeter = newArray(nResults);
standard = newArray(nResults);
min = newArray(nResults);
max = newArray(nResults);
feret’s = newArray(nResults);
integrated =newArray(nResults);
background =newArray(nResults);

for(i=0; i<nResults-1; i++) {
area[i] = getResult("Area", i);
mean[i] = getResult("Mean", i);
perimeter[i] = getResult("Perim.", i);
standard[i] = getResult("StdDev", i);
min[i] = getResult("Min", i);
max[i] = getResult("Max", i);
feret’s[i] = getResult("FeretAngle", i);
integrated[i] = getResult("RawIntDen", i);

// Create new arrays for the X and Y coordinates of all particles
locationArrayX= newArray(nResults);
locationArrayY= newArray(nResults);

// Store X and Y coordinates in the created arrays
locationArrayX[i] = getResult("X", i);
locationArrayY[i] = getResult("Y", i);
}

//The reason I duplicate the image is because if I try to measure the mean of a rectangular selection, Fiji thinks I want to measure the means of the particles within the selection. So, I do the mean measurements in a duplicate with no thresholding applied
selectWindow("1");
run("Set Measurements...", "area mean redirect=None decimal=2");
for (i=0; i<nResults-1; i++) {
// Make a rectangular selection of width and height 200, centred around the particle
makeRectangle(locationArrayX[i], locationArrayY[i], 200, 200);
}

if (isOpen("Results")) {
selectWindow("Results");
run("Close");
}
roiManager("Measure");

for(i=0; i<nResults-1; i++) {
background[i] = getResult("Mean", i);
}

for(i=0; i<nResults-1; i++) {
setResult("Area", i, area[i]);
setResult("Mean", i, mean[i]);
setResult("Perim.", i, perimeter[i]);
setResult("StdDev", i, standard[i]);
setResult("Min", i, min[i]);
setResult("Max", i, max[i]);
setResult("FeretAngle", i, feret’s[i]);
setResult("RawIntDen", i, integrated[i]);
setResult("Background", i, background[i]);
}

updateResults();
``````

I’m almost there, but I keep getting this indexing error… Any ideas? Thank you,
Jacklin and Antri

You could enormously clean up this macro code.
I believe it does what you want … almost. There is still a concatenation to do …
Good luck

``````setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
img=getImageID();
run("Duplicate...", "title=1 ");
run("Duplicate...", "title=2 ");

// Convert image to 8-bit greyscale
run("8-bit");
//setBatchMode(true);
setAutoThreshold("Default dark");
//run("Threshold...");
// Choose regions with Greyvalue between 2 and 255 only
// setThreshold(2, 255);
run("Set Measurements...", "area mean centroid center perimeter standard min fit feret's integrated redirect=None decimal=2");

// Display measurements (including Raw Integrated Density)
roiManager("Show All with labels");
run("Flatten");

// Create new arrays for all results
locationArrayX= newArray(nResults);
locationArrayY= newArray(nResults);
area = newArray(nResults);
mean = newArray(nResults);
perimeter = newArray(nResults);
standard = newArray(nResults);
min = newArray(nResults);
max = newArray(nResults);
feret’s = newArray(nResults);
integrated =newArray(nResults);
background =newArray(nResults);

for(i=0; i<nResults-1; i++) {
// Store all results in the new created arrays
locationArrayX[i] = getResult("X", i);
locationArrayY[i] = getResult("Y", i);
area[i] = getResult("Area", i);
mean[i] = getResult("Mean", i);
perimeter[i] = getResult("Perim.", i);
standard[i] = getResult("StdDev", i);
min[i] = getResult("Min", i);
max[i] = getResult("Max", i);
feret’s[i] = getResult("FeretAngle", i);
integrated[i] = getResult("RawIntDen", i);

}
// Show all Array
Array.show(locationArrayX);
Array.show(locationArrayY);
Array.show(area);
Array.show(mean);
Array.show(perimeter);
Array.show(standard);
Array.show(min);
Array.show(max);
Array.show(feret’s);
Array.show(integrated);

// Show the results
selectWindow("Results");

roiManager("reset");
//The reason I duplicate the image is because if I try to measure the mean
//of a rectangular selection, Fiji thinks I want to measure the means of the particles within the selection. So, I do the mean measurements in a duplicate with no thresholding applied
selectWindow("1");

// Make a rectangular selection of width and height 200, centred around the particle
for (i=0; i<nResults -1; i++) {
// Make a rectangular selection of width and height 200, centred around the particle
makeRectangle(locationArrayX[i], locationArrayY[i], 200, 200);
}
selectWindow("Results");
close("Results");

// The old results table is closed and therefore we open a new one
roiManager("Measure");

showMessage("Warning","Compare the measurements \nin all the Array with those in the windowResults of all ROI mesurements");

``````

Hi Matthew,

Victory! The indexing error is gone and the code runs great with correct results. Here’s my finalised code:

``````setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
img=getImageID();
run("Duplicate...", "title=1 ");
run("Duplicate...", "title=2 ");

selectWindow("1");
// Convert image to 8-bit greyscale
run("8-bit");
setBatchMode(true);
setAutoThreshold("Default dark");
//run("Threshold...");
// Choose regions with Greyvalue between 2 and 255 only
setThreshold(2, 255);
run("Set Measurements...", "area mean centroid perimeter standard min feret's integrated redirect=None decimal=2");

// Display measurements (including Raw Integrated Density)

//Create new arrays for standard results
area = newArray(nResults);
mean = newArray(nResults);
perimeter = newArray(nResults);
standard = newArray(nResults);
min = newArray(nResults);
max = newArray(nResults);
feret’s = newArray(nResults);
integrated =newArray(nResults);

background =newArray(nResults);
locationArrayX= newArray(nResults);
locationArrayY= newArray(nResults);

for(i=0; i<nResults-1; i++) {
area[i] = getResult("Area", i);
mean[i] = getResult("Mean", i);
perimeter[i] = getResult("Perim.", i);
standard[i] = getResult("StdDev", i);
min[i] = getResult("Min", i);
max[i] = getResult("Max", i);
feret’s[i] = getResult("FeretAngle", i);
integrated[i] = getResult("RawIntDen", i);
locationArrayX[i] = getResult("X", i);
locationArrayY[i] = getResult("Y", i);
}

selectWindow("2");
run("Set Measurements...", "area mean redirect=None decimal=2");
for (i=0; i<nResults-1; i++) {
// Make a rectangular selection of width and height 200, centred around the particle
makeRectangle(locationArrayX[i], locationArrayY[i], 200, 200);
background[i] = getResult("Mean", i);
}

for(i=0; i<nResults-1; i++) {
setResult("Area", i, area[i]);
setResult("Mean", i, mean[i]);
setResult("Perim.", i, perimeter[i]);
setResult("StdDev", i, standard[i]);
setResult("Min", i, min[i]);
setResult("Max", i, max[i]);
setResult("FeretAngle", i, feret’s[i]);
setResult("RawIntDen", i, integrated[i]);
setResult("Background", i, background[i]);
}

updateResults();
``````

Thank you for your kind assistance Here’s a screenshot of what my final results table looks like (just what I wanted)

P.S. I attempted to run the code that you posted on Mar 19, but the measurements in the array did not match up with those in windowResults. And instead of creating a new column for ROI measurements under the title “background”, the results table displayed them inter-mixed with the array measurements.

Update

So, the macro I wrote actually doesn’t work. A second look at the table posted earlier shows that instead measuring the mean of the ROI and publishing it as ‘Background’, Fiji just publishes the previous mean measurement from the ‘Analyze Particles’ section. That’s why the Mean and Background columns are identical…

Any ideas how to fix this? Been pulling my hair out today trying to remedy the issue to no avail Much appreciated,
Jacklin and Antri

@Jacklin_and_Antri
Hello
Below my macro. But she does not respond to your instructions. Indeed I took your image to test codes.
But I think you should take a look and peel the macro line by line

``````requires("1.52u");
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
img=getImageID();
setBatchMode(true);
selectImage(img);
//-------------------------------
//Begin macro
run("Duplicate...", "title=1");
run("8-bit");
run("Duplicate...", "title=2");
setAutoThreshold("Default dark");
//run("Threshold...");
//setThreshold(3, 255);
//-------------------------------------------------------------
//1.  Identify the impact points
run("Set Measurements...", "area centroid redirect=None decimal=2");
//----------------------------------------------------------------
//2.  Measure average intensity "pointMean"
run("Set Measurements...", "area mean centroid redirect=None decimal=2");
run("Clear Results");
n=roiManager("Count");
for(i=0;i<n-1;i++)
{
roiManager("Select", i);
roiManager("Measure");}
//---------------------------------------------------------------
//2. Record average intensity values ​​in an array
//Create Array to stoke Mean
pointMean_Array=newArray(nResults);
//-----------------------------------------------------
// Store pointMean_Array with values
for(i=0;i<nResults-1;i++)
{
pointMean_Array[i]=getResult("Mean",i);
}
// Show pointMean_Array
Array.show(pointMean_Array);
//----------------------------------------------------
//3. Circle the impact points with a circle with a diameter of 100
for(j=0;j<nResults-1;j++)
{
roiManager("Select", j);
X=getResult("X",j);
Y=getResult("Y",j);
run("Specify...", "width=100 height=100 x="+X+" y="+Y+" oval centered");
roiManager("Update");
}
//--------------------------------------------------------------------------
// Measure the average intensity in the circle
run("Set Measurements...", "area mean centroid redirect=None decimal=2");
run("Clear Results");
n=roiManager("Count");
for(i=0;i<n-1;i++)
{
roiManager("Select", i);
roiManager("Measure");}

// enregistrer les valeurs ovalMean dans un tableau
//Create Array to stoke ovalMean
ovalMean_Array=newArray(nResults);
//Record the values ​​of the average intensity in the circle, in an array
//-----------------------------------------------------
// Store ovalMean_Array with values
for(i=0;i<nResults-1;i++)
{
ovalMean_Array[i]=getResult("Mean",i);
}
// Show ovalMean_Array
Array.show(ovalMean_Array);
//---------------------------------------------
// Create the table and compile the measurement values
Table.create("Mean");
// set a whole column
Table.setColumn("Point",pointMean_Array);
Table.setColumn("Oval",ovalMean_Array);
//---------------------------------------------------
//End of macro
close("*");close("ROI Manager");close("Results");close("ovalMean_Array");close("pointMean_Array");
setBatchMode(false);
exit("Processing is complete
``````