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...", " ");
selectWindow("radiation.iso400.ss0.image012.png");

// 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
selectWindow("radiation.iso400.ss0.image012-1.png");

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 :slight_smile: Thank you!

Jacklin & Antri

hi
@Jacklin_and_Antri

I have slightly changed your macro-code.
I suggest you go through a spreadsheet.
Open 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)
run("Analyze Particles...", "display add");

// 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);

roiManager("Add");
}
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 :smiley: 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.

Also read this:

You may have to go through the arrays and concatenate:
Please deposit your finds.

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)
run("Analyze Particles...", "display add");

//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);
	roiManager("Add");
}

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?
Screen Shot 2020-03-19 at 5.55.06 PM

Thank you,
Jacklin and Antri

Hi
@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 …
Please deposit your finds. We all learn from others.
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)
run("Analyze Particles...", "display add");
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);
roiManager("Add");
}
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)
run("Analyze Particles...", "display add");

//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 :slight_smile:
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 :frowning:

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
Can you tell me about your results, if you don’t mind.

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");
run("Analyze Particles...", "display add");
//----------------------------------------------------------------
//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