CLIJ2 gives wrong output for getMeanOfMaskedPixels

I noticed some strange results when running some tests with CLIJ2_getMeanOfMaskedPixels in a ImageJ macro. After digging around I think I found the culprit.

The sum of the mask max-es out at 16777216 (2^24), so for very large images the mean has a positive bias.

Anyway, here’s my ugly code that demonstrates the issue:

run("Close All");
run("Blobs");
run("16-bit");
run("Multiply...", "value=255");

imgName = getTitle();

run("CLIJ2 Macro Extensions", "cl_device=");
Ext.CLIJ2_clear();
Ext.CLIJ2_push(imgName);

Ext.CLIJ2_getDimensions(imgName,w, h, d);

for(n = 1;n<25;n++){
	// generate 2d image by stamping input n*n times
	Ext.CLIJ2_create2D(input, w*n, h*n, 16);
	for (nx = 0; nx < n; nx++) {
		for (ny = 0; ny < n; ny++) {
			Ext.CLIJ2_paste2D(imgName, input, nx*w, ny*h);
		}
	}
	
	Ext.CLIJ2_threshold(input, mask, 127);
	Ext.CLIJ2_getMeanOfMaskedPixels(input, mask, mean_of_masked_pixels);
	
	Ext.CLIJ2_getSumOfAllPixels(mask,nr_of_masked_pixels);
	Ext.CLIJ2_multiplyImages(input,mask,temp_img);
	Ext.CLIJ2_getSumOfAllPixels(temp_img,sum_of_masked_pixels);
	manual_mean = sum_of_masked_pixels / nr_of_masked_pixels;
	Ext.CLIJ2_release(temp_img);
	
	print("n: "+n+", mean of masked pixels: " + mean_of_masked_pixels + ", manual_mean: "+manual_mean+ ", sum_of_masked_pixels: " + sum_of_masked_pixels + ", nr_of_masked_pixels: " + nr_of_masked_pixels);
	
	Ext.CLIJ2_release(input);
	Ext.CLIJ2_release(mask);
}

Which outputs:

n: 1, mean of masked pixels: 26338.8346, manual_mean: 26338.8346, sum_of_masked_pixels: 1712656384, nr_of_masked_pixels: 65024
n: 2, mean of masked pixels: 26379.4724, manual_mean: 26379.4724, sum_of_masked_pixels: 6.8612E9, nr_of_masked_pixels: 260096
n: 3, mean of masked pixels: 26411.6098, manual_mean: 26411.6098, sum_of_masked_pixels: 1.5456E10, nr_of_masked_pixels: 585216
n: 4, mean of masked pixels: 26422.5827, manual_mean: 26422.5827, sum_of_masked_pixels: 2.7490E10, nr_of_masked_pixels: 1040384
n: 5, mean of masked pixels: 26214.8157, manual_mean: 26214.8157, sum_of_masked_pixels: 4.2615E10, nr_of_masked_pixels: 1625600
n: 6, mean of masked pixels: 25957.965, manual_mean: 25957.965, sum_of_masked_pixels: 6.0764E10, nr_of_masked_pixels: 2340864
n: 7, mean of masked pixels: 25794.278, manual_mean: 25794.278, sum_of_masked_pixels: 8.2185E10, nr_of_masked_pixels: 3186176
n: 8, mean of masked pixels: 25678.3189, manual_mean: 25678.3189, sum_of_masked_pixels: 1.0686E11, nr_of_masked_pixels: 4161536
n: 9, mean of masked pixels: 25606.1888, manual_mean: 25606.1888, sum_of_masked_pixels: 1.3487E11, nr_of_masked_pixels: 5266944
n: 10, mean of masked pixels: 25826.303, manual_mean: 25826.303, sum_of_masked_pixels: 1.6793E11, nr_of_masked_pixels: 6502400
n: 11, mean of masked pixels: 26009.7487, manual_mean: 26009.7487, sum_of_masked_pixels: 2.0464E11, nr_of_masked_pixels: 7867904
n: 12, mean of masked pixels: 26137.6395, manual_mean: 26137.6395, sum_of_masked_pixels: 2.4474E11, nr_of_masked_pixels: 9363456
n: 13, mean of masked pixels: 25984.2505, manual_mean: 25984.2505, sum_of_masked_pixels: 2.8554E11, nr_of_masked_pixels: 10989056
n: 14, mean of masked pixels: 25353.5362, manual_mean: 25353.5362, sum_of_masked_pixels: 3.2312E11, nr_of_masked_pixels: 12744704
n: 15, mean of masked pixels: 24855.3222, manual_mean: 24855.3222, sum_of_masked_pixels: 3.6364E11, nr_of_masked_pixels: 14630400
n: 16, mean of masked pixels: 24462.5906, manual_mean: 24462.5906, sum_of_masked_pixels: 4.0721E11, nr_of_masked_pixels: 16646144
n: 17, mean of masked pixels: 27006.1172, manual_mean: 27006.1172, sum_of_masked_pixels: 4.5309E11, nr_of_masked_pixels: 16777216
n: 18, mean of masked pixels: 29925.3594, manual_mean: 29925.3594, sum_of_masked_pixels: 5.0206E11, nr_of_masked_pixels: 16777216
n: 19, mean of masked pixels: 32999.7852, manual_mean: 32999.7852, sum_of_masked_pixels: 5.5364E11, nr_of_masked_pixels: 16777216
n: 20, mean of masked pixels: 36273.957, manual_mean: 36273.957, sum_of_masked_pixels: 6.0858E11, nr_of_masked_pixels: 16777216
n: 21, mean of masked pixels: 39674.8867, manual_mean: 39674.8867, sum_of_masked_pixels: 6.6563E11, nr_of_masked_pixels: 16777216
n: 22, mean of masked pixels: 43271.1406, manual_mean: 43271.1406, sum_of_masked_pixels: 7.2597E11, nr_of_masked_pixels: 16777216
n: 23, mean of masked pixels: 47062.7188, manual_mean: 47062.7188, sum_of_masked_pixels: 7.8958E11, nr_of_masked_pixels: 16777216
n: 24, mean of masked pixels: 50957.0625, manual_mean: 50957.0625, sum_of_masked_pixels: 8.5492E11, nr_of_masked_pixels: 16777216

Hey @lmvoortman,

interesting! Thanks for reporting this issue. I just need some clarification: In your output it appears that mean and manual mean always ouput the same value. Thus, I see no issue with the GetMeanOfMaskedPixels method. What am I missing?

Thanks!

Cheers,
Robert

Yes, sorry, not the best explanation of what is going on :slight_smile:

The mean (both getMeanOfMaskedPixels, and the manual version) should stay more of less the same (26k) for all the image sizes (it’s just a stamped copy)

The problem I think is in getSumOfAllPixels on the mask which returns nr_of_masked_pixels. This should just keep growing with n^2, but this hits the 24bit limit of 16777216.

I created the ‘manual mean’ to mimic the way getMeanOfMaskedPixels calculates the mean value.

1 Like

and a fancy plot to show the weird behaviour:

Yes, point taken. Very good observation and great example macro! I just fixed the issue by copying over some changes I recently did on the python side.

If you update your Fiji, it should output this when running your macro:

n: 1, mean of masked pixels: 26333.4882, manual_mean: 26333.4882, sum_of_masked_pixels: 1712308736, nr_of_masked_pixels: 65024
n: 2, mean of masked pixels: 26333.5, manual_mean: 26333.5, sum_of_masked_pixels: 6.8492E9, nr_of_masked_pixels: 260096
n: 3, mean of masked pixels: 26333.4908, manual_mean: 26333.4908, sum_of_masked_pixels: 1.5411E10, nr_of_masked_pixels: 585216
n: 4, mean of masked pixels: 26333.4961, manual_mean: 26333.4961, sum_of_masked_pixels: 2.7397E10, nr_of_masked_pixels: 1040384
n: 5, mean of masked pixels: 26333.4753, manual_mean: 26333.4753, sum_of_masked_pixels: 4.2808E10, nr_of_masked_pixels: 1625600
n: 6, mean of masked pixels: 26333.4821, manual_mean: 26333.4821, sum_of_masked_pixels: 6.1643E10, nr_of_masked_pixels: 2340864
n: 7, mean of masked pixels: 26333.4649, manual_mean: 26333.4649, sum_of_masked_pixels: 8.3903E10, nr_of_masked_pixels: 3186176
n: 8, mean of masked pixels: 26333.4764, manual_mean: 26333.4764, sum_of_masked_pixels: 1.0959E11, nr_of_masked_pixels: 4161536
n: 9, mean of masked pixels: 26333.5301, manual_mean: 26333.5301, sum_of_masked_pixels: 1.3870E11, nr_of_masked_pixels: 5266944
n: 10, mean of masked pixels: 26333.4828, manual_mean: 26333.4828, sum_of_masked_pixels: 1.7123E11, nr_of_masked_pixels: 6502400
n: 11, mean of masked pixels: 26333.4782, manual_mean: 26333.4782, sum_of_masked_pixels: 2.0719E11, nr_of_masked_pixels: 7867904
n: 12, mean of masked pixels: 26333.4523, manual_mean: 26333.4523, sum_of_masked_pixels: 2.4657E11, nr_of_masked_pixels: 9363456
n: 13, mean of masked pixels: 26333.5593, manual_mean: 26333.5593, sum_of_masked_pixels: 2.8938E11, nr_of_masked_pixels: 10989056
n: 14, mean of masked pixels: 26333.4186, manual_mean: 26333.4186, sum_of_masked_pixels: 3.3561E11, nr_of_masked_pixels: 12744704
n: 15, mean of masked pixels: 26333.5262, manual_mean: 26333.5262, sum_of_masked_pixels: 3.8527E11, nr_of_masked_pixels: 14630400
n: 16, mean of masked pixels: 26333.4488, manual_mean: 26333.4488, sum_of_masked_pixels: 4.3835E11, nr_of_masked_pixels: 16646144
n: 17, mean of masked pixels: 26333.6747, manual_mean: 26333.6747, sum_of_masked_pixels: 4.9486E11, nr_of_masked_pixels: 18791936
n: 18, mean of masked pixels: 26333.5643, manual_mean: 26333.5643, sum_of_masked_pixels: 5.5479E11, nr_of_masked_pixels: 21067776
n: 19, mean of masked pixels: 26333.4866, manual_mean: 26333.4866, sum_of_masked_pixels: 6.1814E11, nr_of_masked_pixels: 23473664
n: 20, mean of masked pixels: 26333.4929, manual_mean: 26333.4929, sum_of_masked_pixels: 6.8492E11, nr_of_masked_pixels: 26009600
n: 21, mean of masked pixels: 26333.4375, manual_mean: 26333.4375, sum_of_masked_pixels: 7.5513E11, nr_of_masked_pixels: 28675584
n: 22, mean of masked pixels: 26333.5719, manual_mean: 26333.5719, sum_of_masked_pixels: 8.2876E11, nr_of_masked_pixels: 31471616
n: 23, mean of masked pixels: 26333.3512, manual_mean: 26333.3512, sum_of_masked_pixels: 9.0581E11, nr_of_masked_pixels: 34397696
n: 24, mean of masked pixels: 26333.3946, manual_mean: 26333.3946, sum_of_masked_pixels: 9.8629E11, nr_of_masked_pixels: 37453824

And I have the feeling that computing the sum became faster.

Could you please confirm the bugfix? I would then update downstream libraries.

Thanks a lot for reporting this! :heart_decoration:

Cheers,
Robert

1 Like

wow, that was fast.
You’re my new hero! :star_struck:

And yes, it works now!

1 Like

Also, much more accurate now!

You are the hero of good scientific practice! Thanks again. You made CLIJ better today!

1 Like