NOTICE! This is a static HTML version of a legacy Fiji BugZilla bug.

The Fiji project now uses GitHub Issues for issue tracking.

Please file all new issues there.

Bug 420 - Problem with 32bit image containing zeros
Problem with 32bit image containing zeros
Status: RESOLVED FIXED
Product: Fiji
Classification: Unclassified
Component: Other
unspecified
PC Linux
: P2 normal
Assigned To: ImageJ Bugs Mailing List
Depends on:
Blocks:
 
Reported: 2012-04-11 20:27 CDT by Sebastian Rhode
Modified: 2012-09-18 20:35 CDT
2 users (show)

See Also:

Description Sebastian Rhode 2012-04-11 20:27:32 CDT
Hi,

I open an 32bit image from our image database, which is the result of a ratiomatric anlysis. Areas with cells contains values >0, but during the ratio calculation there was an threshold, so that certain areas inside the image will be set to zero.

Inside Fiji I drew some ROIs, which I usually plot over time and to do so I wrote macro, which cycles through all the frames, calulates the mean of every ROIs and plots them. Unfortunately this does not work, when all pixels inside one ROI (for instance a background ROI) are zero.

I also create a new images with 10 frames and all zeros inside from File --> New, drew an ROI and started the macro. The same error message came up.


java.lang.NullPointerException: null
	 at ij.plugin.filter.Analyzer.saveResults(Analyzer.java:409)
	 at ij.plugin.filter.Analyzer.measure(Analyzer.java:241)
	 at ij.plugin.frame.RoiManager.multiMeasure(RoiManager.java:882)
	 at ij.plugin.frame.RoiManager.runCommand(RoiManager.java:1612)
	 at ij.macro.Functions.roiManager(Functions.java:2400)
	 at ij.macro.Functions.getFunctionValue(Functions.java:215)
	 at ij.macro.Interpreter.getFactor(Interpreter.java:1296)
	 at ij.macro.Interpreter.getTerm(Interpreter.java:1267)
	 at ij.macro.Interpreter.getStringExpression(Interpreter.java:1403)
	 at ij.macro.Interpreter.getStringTerm(Interpreter.java:1226)
	 at ij.macro.Interpreter.getString(Interpreter.java:1183)
	 at ij.macro.Interpreter.doStatement(Interpreter.java:259)
	 at ij.macro.Interpreter.doStatements(Interpreter.java:202)
	 at ij.macro.Interpreter.run(Interpreter.java:103)
	 at ij.macro.Interpreter.run(Interpreter.java:73)
	 at CLI.Refresh_Macros.runScript(Refresh_Macros.java:56)
	 at common.RefreshScripts.runScript(RefreshScripts.java:325)
	 at fiji.scripting.TextEditor$Tab$6.execute(TextEditor.java:1216)
	 at fiji.scripting.TextEditor$Executer$1.run(TextEditor.java:1776)

When I addes 0.0001 to the complete image, the error was gone. So it looks to me like the mean value calulation fails under certain circumstances. I also tries to change Misc Option - Divide by zero value from inifinity to 0.001, but that did not help.

Here is the macro code, if you want to try it out.



// Author: Sebastian Rhode
// Date: 2011-04-26

version_number = 1.6;

// marco for plotting mutiple lines from up-to 8 ROIs inside one plot
// only works with time-lapse images
// does not work with image 5D format

// get title from active window
title_orig = getTitle();
selectWindow(title_orig);
imagedir = getInfo("image.directory")
imagefilename = getInfo("image.filename")
//print(imagedir);
print(imagedir + imagefilename);
// get dimension from original image
getDimensions(w,h,ch,sl,fr);
print("X :",w,"Y :",h,"CHANNELS :",ch,"SLICES :",sl,"FRAMES :",fr);

setBatchMode(true);
// create maximum & minmum intensity projetion
run("Z Project...", "start=1 stop="+toString(fr)+" projection=[Max Intensity]");
getStatistics(areaMax, meanMax, minMax, maxMax);
selectWindow(title_orig);
run("Z Project...", "start=1 stop="+toString(fr)+" projection=[Min Intensity]");
// determine the maximum pixel value to adjust the y-scaling of the plot
getStatistics(areaMin, meanMin, minMin, maxMin);
close();

print("Min / Max : ",minMin," / ",maxMax);

Dialog.create("Multiple ROI Kinetics");
Dialog.addMessage("Version Number: " + toString(version_number,1));
Dialog.addNumber("Time per frame [ms]",1);
Dialog.addCheckbox("Plot Data Points", false);
Dialog.addNumber("Line Width for Lines",2);
Dialog.addNumber("Line Width for ROIs",2);
//Dialog.addCheckbox("Inculde Min & Max in result table", false);
Dialog.addCheckbox("ROIs added via Time Series Analyzer", false);
Dialog.addCheckbox("Save Results as TXT-File", false);
Dialog.addCheckbox("Save Results as XLS-File", false);
Dialog.addCheckbox("Show Results in Python - MatPlotLib", false);

Dialog.show();
timeframe = Dialog.getNumber();
plotpoints = Dialog.getCheckbox();
lw_plot = Dialog.getNumber();
lw_roi = Dialog.getNumber();
//minmax = Dialog.getCheckbox();
roiadd = Dialog.getCheckbox();
savetxt = Dialog.getCheckbox();
savexls = Dialog.getCheckbox();
openmpl = Dialog.getCheckbox();

run("Set Measurements...", "  mean display redirect=None decimal=3");
//if (minmax == true){
//	run("Set Measurements...", "  mean min display redirect=None decimal=3");
//	}
//else if (minmax == false){
//	run("Set Measurements...", "  mean display redirect=None decimal=3");	
//	}

// specify plot dimensions
run("Profile Plot Options...", "width=600 height=400 minimum=0 maximum=0 draw");

numROI = roiManager("Count");
print("NumROI :  ",numROI);
if (numROI >= 9) {
	showMessage("Error Message","Too many ROIs - only 8 are possible ...");
	exit();
	}

frames = newArray(fr);
roi1  = newArray(fr); // ROI number 1
roi2  = newArray(fr);
roi3  = newArray(fr);
roi4  = newArray(fr);
roi5  = newArray(fr);
roi6  = newArray(fr);
roi7  = newArray(fr);
roi8  = newArray(fr);

if (roiadd == true) {
	lb = newArray("Mean(ROI001)","Mean(ROI002)","Mean(ROI003)","Mean(ROI004)","Mean(ROI005)","Mean(ROI006)","Mean(ROI007)","Mean(ROI008)");	
}
if (roiadd == false) {
	lb = newArray("Mean1","Mean2","Mean3","Mean4","Mean5","Mean6","Mean7","Mean8");
}

// create color list for ROIs
List.set("1","red"); // color for ROI 1
List.set("2","green");
List.set("3","blue");
List.set("4","magenta");
List.set("5","orange");
List.set("6","cyan");
List.set("7","yellow");
List.set("8","black");

// adjust color properties for all ROIs
for (i=1; i<=numROI; i++) {
	roiManager("Select", i-1);
	colorvalue = List.get(toString(i));
	roiManager("Set Color", colorvalue);
	roiManager("Set Line Width", lw_roi);
	}

roiManager("Deselect");
roiManager("Multi Measure");

// create array containing the frame numbers
for (i=1; i<=fr; i++) {
	frames[i-1] = i * timeframe;
	//setResult("Time", i-1, i * timeframe);
	setResult("Time", i-1, frames[i-1]);
	}


for (i=1; i<=fr; i++) {
	if (numROI == 1) {
		roi1[i-1] = getResult(lb[0],i-1);
		}
	if (numROI == 2) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		}
	if (numROI == 3) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);	
		}
	if (numROI == 4) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);
		roi4[i-1] = getResult(lb[3],i-1);
		}
	if (numROI == 5) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);
		roi4[i-1] = getResult(lb[3],i-1);
		roi5[i-1] = getResult(lb[4],i-1);
		}
	if (numROI == 6) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);
		roi4[i-1] = getResult(lb[3],i-1);
		roi5[i-1] = getResult(lb[4],i-1);
		roi6[i-1] = getResult(lb[5],i-1);
		}
	if (numROI == 7) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);
		roi4[i-1] = getResult(lb[3],i-1);
		roi5[i-1] = getResult(lb[4],i-1);
		roi6[i-1] = getResult(lb[5],i-1);
		roi7[i-1] = getResult(lb[6],i-1);	
		}
	if (numROI == 8) {
		roi1[i-1] = getResult(lb[0],i-1);
		roi2[i-1] = getResult(lb[1],i-1);
		roi3[i-1] = getResult(lb[2],i-1);
		roi4[i-1] = getResult(lb[3],i-1);
		roi5[i-1] = getResult(lb[4],i-1);
		roi6[i-1] = getResult(lb[5],i-1);
		roi7[i-1] = getResult(lb[6],i-1);
		roi8[i-1] = getResult(lb[7],i-1);		
		}
	}

// do the plots
Plot.create("Line Plot Test", "Frame Number / Time [ms]", "Mean Intensity [cts]", frames, roi1);
Plot.setLimits(1, fr*timeframe*1.02, minMin*1.3, maxMax*1.1);
//Plot.setLimits(1, fr*timeframe*1.02, minMin, maxMax*0.8);
Plot.setLineWidth(lw_plot);
if (plotpoints == true) {
	Plot.add("Circle", frames, roi1);	
	}
// ROI 2
if (numROI >= 2) {
	Plot.setColor(List.get(toString(2)));
	Plot.add("Line", frames, roi2);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi2);	
		}
}
// ROI 3
if (numROI >= 3) {
	Plot.setColor(List.get(toString(3)));
	Plot.add("Line", frames, roi3);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi3);	
	}
}
// ROI 4
if (numROI >= 4) {
	Plot.setColor(List.get(toString(4)));
	Plot.add("Line", frames, roi4);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi4);	
	}
}
// ROI 5
if (numROI >= 5) {
	Plot.setColor(List.get(toString(5)));
	Plot.add("Line", frames, roi5);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi5);	
	}
}
// ROI 6
if (numROI >= 6) {
	Plot.setColor(List.get(toString(6)));
	Plot.add("Line", frames, roi6);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi6);	
	}
}
// ROI 7
if (numROI >= 7) {
	Plot.setColor(List.get(toString(7)));
	Plot.add("Line", frames, roi7);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi7);	
	}
}
// ROI 8
if (numROI == 8) {
	Plot.setColor(List.get(toString(8)));
	Plot.add("Line", frames, roi8);
	if (plotpoints == true) {
		Plot.add("Circle", frames, roi8);	
	}
}

// ROI 1
Plot.setColor(List.get(toString(1)));
// display the plot
Plot.show();
setBatchMode(false);

if (savetxt == true) {
   	if (nResults==0) {
   		exit("Results table is empty");
   	}
   	else {
   		path = imagedir + imagefilename + "_Results.txt";
   		//print(path);
   		saveAs("Measurements", path);
   	}
}

if (savexls == true) {
	// save contents of Results table in Excel
   	if (nResults==0) {
   		exit("Results table is empty");
   	}
   	else {
   		path = imagedir + imagefilename + "_Results.xls";
   		//print(path);
   		saveAs("Measurements", path);
   		//exec("cmd", "/c", "start", "excel.exe", "c:\\Results.xls");
   	}
}

if (openmpl == true) {
   	if (nResults==0) {
   		exit("Results table is empty");
   	}
   	else {
   		path = imagedir + imagefilename + "_Results.txt";
   		saveAs("Measurements", path);
   		exec("cmd", "/c","start", "python.exe", "c:/Dokumente und Einstellungen/sebastian.rhode/Eigene Dateien/Sebi/Projects_TILL/LA_Software/Online_Analysis/kinetics_FIJI.py", "run");
   	}
}
Comment 1 Johannes Schindelin 2012-04-11 23:25:38 CDT
This is very deep in ImageJ 1.* code so I suspect a bug there.

line 409 of Analyzer reads like this:

if (counter<=MAX_STANDARDS && !(stats.umean==0.0&&counter==1&&umeans[0]!=0f)) {

(see http://fiji.sc/cgi-bin/gitweb.cgi?p=ImageJA.git;a=blob;f=src/main/java/ij/plugin/filter/Analyzer.java;hb=refs/heads/master#l409)

So I tested whether stats can be null. The stats variable is passed from line 241 in the same file and since the image is likely not to be redirected, the statistics are likely to be obtained using imp.getStatistics(measurements).

However, this code returns a non-null statistics instance:

imp = new ImagePlus("Black", new FloatProcessor(1, 1));
measurements = Analyzer.AREA | Analyzer.MEAN | Analyzer.MIN_MAX;
print(imp.getStatistics(measurements));

So I suspect that the bug is that umeans is null.

Unfortunately, I cannot spend more time on this issue, and even if I did, my changes would be unlikely to be taken as-are, so I leave this issue in the ballpark of the ImageJ 1.* maintainer.
Comment 2 Wayne Rasband 2012-04-11 23:49:02 CDT
This bug is fixed in the ImageJ 1.46k daily build. 
Comment 3 Johannes Schindelin 2012-04-12 07:30:54 CDT
Wayne: while it is good that you solved the bug, it is good that you did not close the bug because there is not enough information for mere mortals without mystical abilities to follow what has been done to resolve the issue.
Comment 4 Wayne Rasband 2012-04-12 18:20:55 CDT
I fixed this bug in v1.46k18 by changing line 409 of ij.plugin.filter.Analyzer.java from

  if (counter<=MAX_STANDARDS && !(stats.umean==0.0&&counter==1&&umeans[0]!=0f)) {

to

  if (counter<=MAX_STANDARDS && !(stats.umean==0.0&&counter==1&&umeans!=null && umeans[0]!=0f)) {

-wayne

Comment 5 Johannes Schindelin 2012-04-12 19:09:29 CDT
Thanks. But why is umeans == null when all the pixel values are 0.0, but != null when the pixel values are slightly larger but still constant?

To be sure, testing for umeans == null before testing umeans[0] is a well-known defensive programming technique, but in this case, it feels as if something is wrong when the contract is broken only for one very specific constant value.
Comment 6 Johannes Schindelin 2012-04-20 22:33:41 CDT
I will leave this bug open until it is clear why the "umeans" field is not consistently initialised.
Comment 7 Johannes Schindelin 2012-09-18 20:35:08 CDT
I guess I will never know ;-)