Strange numbers in average values

imagej

#1

Hello,
I am trying to use Imagej for my thesis. I have few sets of five photographs (black and white), I would like to make an average of every five photographs. I wrote a simple macro (code below) to do this, but I was not sure whether the output is correct. So I made a histogram for every single photography and made an average value of Mean grey value (using handheld calculator), I was surprised, when I found out, that the Mean grey value in histogram of averaged photo was different. To exclude possible mistake in my algorithm I tried the Grouped Z Projection, the histogram Mean grey value was again completely different value. To exclude possible problem of Imagej I tried GraphicsMagick (gm convert -average), then I made histogram with another different Mean grey value.
I thank in advance for any help, especially help to explain all these different values:
Mean1:76,963
Mean2:77,055
Mean3:76,802
Mean4:76,802
Mean5:76,659
AVGMean(calculator):76,8562
AVGMean(graphicsmagick):76.434
AVGMean(GroupedZProjection):76,443
AVGMean(MyAlgorithm):76,636

My code:

input = "/home/user/Documents/Thesis/IRPHOTO/input/";
output = "/home/user/Documents/Thesis/IRPHOTO/output/";

setBatchMode(true); 
list = getFileList(input);
i=0;
open(input + list[i]);
id1 = getImageID;

j = i + 1;
open(input + list[j]);
id2 = getImageID;

k = i + 2;
open(input + list[k]);
id3 = getImageID;

l = i + 3;
open(input + list[l]);
id4 = getImageID;
m = i + 4;
open(input + list[m]);
id5 = getImageID;

id1=(id1 + id2 + id3 + id4 + id5)/5;
i = i + 50;
saveAs("Jpeg", output + i);

   	close(); 

setBatchMode(false);

#2

Good day!

What do you expect fom this code line

id1 = (id1 + id2 + id3 + id4 + id5) / 5;

The mean gray value of an achromatic image is best obtained with:

run("Set Measurements...", "mean redirect=None decimal=6");
run("Measure");

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

Regards

Herbie


#3

This code is not meant to generate Mean grey value of any image. It should make an average photography out of five.
Thanks for quick reply and inspiration.


#4

Here is an example macro that generates the mean image from 4 images:

// generate 4 test images
newImage("Img-1", "8-bit ramp", 256, 256, 1);
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
// make a stack and project it
run("Images to Stack", "name=Stack title=[] use");
run("Z Project...", "projection=[Average Intensity]");

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

If you have your five images open in ImageJ you only need the two last lines of code.

Please note that the mean of images is an image, not a number!

Regards

Herbie


#5

Thank you once more. But my output is an image (different from input images). My code is based on Imagej manual/tutorial:
http://imagej.net/docs/guide/146-29.html#toc-Section-29
in part Image Calculator there is a line:
Average: img1 = (img1 + img2) ⁄ 2
I’m still not sure, why the Z Projecton output is different from GraphicsMagick and manual calculation.


#6

But my output is an image (different from input images).

I don’t understand what you want to tell us.

If you prefer the Image Calculator then go ahead but you will have to write a lot of code to get the mean of 5 images …

run("Images to Stack", "name=Stack title=[] use");
run("Z Project...", "projection=[Average Intensity]");

is the way to go and the result is correct.

Regards

Herbie


#7

Here is an example macro that generates the mean image from 4 images using the Image Calculator:

// generate 4 test images
newImage("Img-1", "8-bit ramp", 256, 256, 1);
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
run("Duplicate...", " ");
run("Rotate 90 Degrees Right");
// average the four images
imageCalculator("Average create", "Img-1","Img-2");
selectWindow("Result of Img-1");
imageCalculator("Average create", "Img-3","Img-4");
selectWindow("Result of Img-3");
imageCalculator("Average create", "Result of Img-1","Result of Img-3");
selectWindow("Result of Result of Img-1");

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

As you can easily recognize, the result image is the same as that obtained with “Z Project…”.

Regards

Herbie


#8

Thank you. I did not mean to offend You. English is not my mother-language.
I appreciate your help. I don’t insist on my algorithm. I was simply curious whether the syntax may be equivalent and I could not understand reasons why are possibly equivalent methods different. For example why is there a difference between results of:
1)5 images to stack->

run("Images to Stack", "name=Stack title=[] use");
run("Z Project...", "projection=[Average Intensity]");`

-> Histogram (Ctrl+H)
2) Histograms of 5 images -> manual calculation of average mean grey value
(Thanks in advance for answer)


#9

Well,

the results depend on the gray-value depth. If your result image is 8bit, then you get only integer values between 0 and 255. If your result image is 32bit float you get up to 8 decimals.

If you take the mean displayed in the histogram window you see a number having 3 decimals. If you use “Measure” you can choose to get up to 9 decimals but the 9th digit is not reliable.

HTH

Herbie


#10

Thank you. I will try to integrate the code into some working macro.
What still seems strange to me is that when I apply Measure to my five photos I get values:
76.963044
77.055167
76.801811
76.801867
76.658722
While Measure on the Z projected average produces:
76.462478
I do not understand how can the average image be darker (in meaning of mean grey value) than any individual input image.
In the photos there are LED in dark and in different photos their position is slightly different, could this be the reason why the average is lower than individual values?

EDIT: I got an idea to add all five photos to a stack and then try the “Statistics” in Image>Stacks>Statistics (this tool is not mentioned in manual), this way I got another “odd” mean value:
76.856122


#11

I think you are confusing the “mean of the stack” and the “mean of the means” and the “grand mean” when the groups are different sizes.
What are you after?


#12

Thanks for an answer.
I am after a mean grey value that would be representative for the five photographs. I expected that by averaging the photographs or by averaging their individual mean grey values I would reduce possible error created by visual artefacts in photographs (since they were taken in dark).
I thought that making an average photography (out of 5 photos) and measuring its mean grey value would produce the same result as calculating average (arithmetic) out of mean grey values of each single photograph (same 5 photos). My last idea was that mean grey value of a stack (of 5 photos) would be the same as the before mentioned arithmetic average (since the number of pixels in 5 photos would be the same as the number of pixels in a stack composed out of 5 photos).


#13

Here is a link to a related question:
http://forum.image.sc/t/calculate-rgb-values-for-all-the-particules/7905/9

With this respect please take into account what Gabriel wrote.

This is basic “Mathematical Statistics” and should be described in the corresponding text books.

Regards

Herbie


#14

Please try the following demo macro that implements three approaches and uses two images (img-1 and img-2):

n = 256;
run("Set Measurements...", "area mean standard modal min area_fraction display redirect=None decimal=6");
newImage("img-1", "32-bit random", n, n, 1);
newImage("img-2", "32-bit random", n, n, 1);
run("Images to Stack", "name=Stack title=[] use keep");
run("Z Project...", "projection=[Average Intensity]");
selectWindow("img-1");
run("Measure");
selectWindow("img-2");
run("Measure");
m1 = getResult("Mean", 0);
m2 = getResult("Mean", 1);
setResult("Mean", nResults, (m1+m2)*0.5);
setResult("Area", nResults-1, n*n );
setResult("Label", nResults-1, "Mean_1&2");
updateResults();
selectWindow("AVG_Stack");
run("Measure");
selectWindow("Stack");
run("Statistics");
setResult("Label", nResults-1, "Stack-Stats");
exit();

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

The results table gives you the following data in the “Mean”-column:

row 1: mean of image img-1
row 2: mean of image img-2
row 3: mean of the mean values from row 1 and row 2
row 4: mean of the stack average
row 5: Stack Statistics of the stack

Regards

Herbie


#15

Thank you for such a complex answer, the link helped me understand how the calculations of mean values work.
The important fact that I forgot to mention (I am sorry about that) is that my photos are all the same size (300x300 pixels), so the methods (mentioned in the linked topic):

Example:
area1 = 2pixel
value at each pixel = 1000
area2 = 4pixel
value at each pixel = 10
Sum( individual means ) / ( number of selections ) = ( 2000 / 2 + 40 / 4 ) / 2 = 1010 / 2 = 505;
Sum( values in all selections ) / Sum( areas of all selections ) = ( 2000 + 40 ) / ( 2 + 4 ) = 340;

give the same results.
I ran the purposed demo macro. I got these results:

img-1	        0.004829
img-2	        0.002379
Mean_1&2	0.003604
AVG_Stack	0.003604
Stack-Stats	0.003604

To make sure I understand these results I modified the script to do the same with my five photos:

setBatchMode(true);
n = 300;
run("Set Measurements...", "area mean standard modal min area_fraction display redirect=None decimal=6");

dir = getDirectory("Choose a directory of images...");
list = getFileList(dir);

for (i=0; i <list.length; i++) {
path = dir + list[i];
open(path); 
}
run("Images to Stack", "name=Stack title=[] use keep");
stackImage = getTitle();

run("Z Project...", "projection=[Average Intensity]");

for (i=0; i <list.length; i++) {
window = list[i];
selectWindow(window);
run("Measure"); 
}
m1 = getResult("Mean", 0);
m2 = getResult("Mean", 1);
m3 = getResult("Mean", 2);
m4 = getResult("Mean", 3);
m5 = getResult("Mean", 4);
setResult("Mean", nResults, (m1+m2+m3+m4+m5)*0.2);
setResult("Area", nResults-1, n*n );
setResult("Label", nResults-1, "Mean_1&2&3&4&5");
updateResults();
selectWindow("AVG_Stack");
run("Measure");
selectWindow("Stack");
run("Statistics");
setResult("Label", nResults-1, "Stack-Stats");
exit();

setBatchMode(false);

and got results:

100_0439.jpg            76.963044
100_0441.jpg            77.055167
100_0442.jpg            76.801811
100_0443.jpg            76.801867
100_0444.jpg            76.658722
Mean_1&2&3&4&5          76.856122
AVG_Stack               76.462478
Stack-Stats             76.856122

I am confused by the mean of AVG_Stack since according to the demo script I would expect the same value as Stack-Stats and Mean_1&2&3&4&5 (and at least a value that is not lower than mean of individual photos). I read the Imagej manual: 28.6.11 Z Project… in:
https://imagej.nih.gov/ij/docs/guide/146-28.html#toc-Subsection-28.6
If I understand correctly it should make an average for every single pixel (not a problem since all photos are the same size) and when I calculate the mean (grey value), it should follow the above mentioned expression:

Sum( values in all selections ) / Sum( areas of all selections )

Which according to the example (mentioned above) should give the same result.


#16

Please post the 5 images (TIF- or PNG-format) you are using, otherwise I see no way to clarify the situation.

BTW, every code line following exit(); has no effect, i.e. in your code setBatchMode(false); must precede exit();

Regards

Herbie


#17

Firstly thanks for the correction, I am not very used to macro syntax (my code is inspired by several working examples of code I found).
Unfortunately the original images are only .jpg (since the device I use to take photos is a modified compact camera Kodak EasyShare M550 that does not allow any other output format and there is no alternative firmware available) and I expect that conversion to .png could cause the distortion.
100_0439100_0441100_0442100_0443100_0444


#18

Thanks for images (that are strongly over-exposed).

I think you simply didn’t change the images to 32bit float.

Use

run("32-bit");

Regards

Herbie


#19

Here is the demo macro for k images in a folder:

n = 300;
run( "Set Measurements...", "area mean standard modal min area_fraction display redirect=None decimal=6" );
dir = getDirectory( "Choose a directory of images..." );
setBatchMode(true);
list = getFileList(dir);
k = list.length;
for ( i=0; i < k; i++ ) { open( dir + list[i] ); run( "32-bit" ); }
run( "Images to Stack", "name=Stack title=[] use keep" );
run( "Z Project...", "projection=[Average Intensity]" );
mn = 0;
for ( i=0; i < k; i++ ) {
	selectImage( list[i] );
	run( "Measure" );
	mn += getResult( "Mean", i );
	close();
}
mn /= k;
setResult( "Mean", nResults, mn );
setResult( "Area", nResults-1, n*n );
setResult( "Label", nResults-1, "Mean_1-" + k );
updateResults();
selectImage( "AVG_Stack" );
run( "Measure" );
close();
selectImage( "Stack" );
run( "Statistics" );
close();
setResult( "Label", nResults-1, "Stack-Stats" );
setBatchMode(false);
exit();

And here is the result window for your five sample images:

HTH

Herbie


#20

Thank you kindly for your great help. I believe my problem is now completely solved.
I am also glad that not all my assumptions were wrong since the result is more precise value of handheld calculator result (mentioned in the first post).