What are the display and processing protocols for NaNs in the various image types

plugins
Tags: #<Tag:0x00007fd548970a70>

#1

I’m wondering if there is a good writeup for how NaNs are handled

Image Type NaN is Displayed as Nan is processed as
RGB
indexed color
8-bit
16-bit
32-bit

Thanks
Ron DeSpain


#2

Dear @rondespain,

as far as I know, NaN is only supported in the 32-bit case when you setting a threshold. Conversions to other image types will replace NaN with 0. How NaNs are processed depends on the implementation of a plugin. Most of the built-in filters seem to ignore NaN in their computations. Additionally, you can use Process > Noise > Remove NaNs… to replace NaN intensities with the median intensity of their neighborhood.

Best,
Stefan


#3

Hello stelfrich
Any idea why the conversion of nans to a value with changeValues isn’t working below?

requires("1.45e");
run("32-bit");  //must be 32 bit

changeValues(200,255,NaN);
changeValues(0,10,NaN);
getStatistics(area,mean);
//print(area,mean);
changeValues(NaN,NaN,mean);
waitForUser("NaNs not changed to mean");
run("8-bit");  
changeValues(0,0,mean);

#4

changeValues(NaN,NaN,mean); does not work as you expect it to work in this case. You will have to iterate the pixels manually and replace NaN instances with mean:

//...
xmax = getWidth();
ymax = getHeight();
for(x=0;x<xmax;x++) { 
	for(y=0;y<ymax;y++) { 
		v=getPixel(x,y);
		if(isNaN(v)) {
			setPixel(x,y,mean);
		} 
	}
} 
//...
Comparisons with `NaN` always evaluate to `false`:

https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.2.3:

NaN is unordered, so:

  • The numerical comparison operators <, <=, >, and >= return false if either or both operands are NaN (§15.20.1).

#5

I am comparing two techniques for replacing flares and darkfield backgrounds with the mean of the image by using NaNs, and ran into a confusing result…possibly a memory problem within ImageJ
Here is the code I used:
requires(“1.45e”);
oit=getTitle();
run(“Duplicate…”, “title=[Conversion Technique]”);
run(“32-bit”);

changeValues(200,255,NaN);
changeValues(0,10,NaN);
getStatistics(area,mean1);
print(“The Mean is: “+mean1+” for the Conversion Technique”);

starttime1=getTime();
run(“8-bit”);
changeValues(0,0,mean1);
run(“32-bit”);
endtime1=getTime();

selectWindow(oit);
run(“Duplicate…”, “title=[Pixel Technique]”);
run(“32-bit”);
changeValues(200,255,NaN);
changeValues(0,10,NaN);
getStatistics(area,mean2);
print(“The Mean is: “+mean2+” for the Pixel Replacement Technique”)
starttime2=getTime();
xmax = getWidth();
ymax = getHeight();
for(x=0;x<xmax;x++) {
for(y=0;y<ymax;y++) {
v=getPixel(x,y);
if(isNaN(v)) {
setPixel(x,y,mean2);
}
}
}
endtime2=getTime();

print("Replacing NaNs via 8bit conversion change time = “+endtime1-starttime1+”\nReplacing NaNs via 32bit pixel replacement time = "+endtime2-starttime2);
run(“Tile”);

// ##########Cycle 2##############

oit=getTitle();
run(“Duplicate…”, “title=[Conversion Technique]”);
run(“32-bit”);

changeValues(200,255,NaN);
changeValues(0,10,NaN);
getStatistics(area,mean1);
print(“The Mean is: “+mean1+” for the Conversion Technique”);

starttime1=getTime();
run(“8-bit”);
changeValues(0,0,mean1);
run(“32-bit”);
endtime1=getTime();

selectWindow(oit);
run(“Duplicate…”, “title=[Pixel Technique]”);
run(“32-bit”);
changeValues(200,255,NaN);
changeValues(0,10,NaN);
getStatistics(area,mean2);
print(“The Mean is: “+mean2+” for the Pixel Replacement Technique”)
starttime2=getTime();
xmax = getWidth();
ymax = getHeight();
for(x=0;x<xmax;x++) {
for(y=0;y<ymax;y++) {
v=getPixel(x,y);
if(isNaN(v)) {
setPixel(x,y,mean2);
}
}
}
endtime2=getTime();

print("Replacing NaNs via 8bit conversion change time = “+endtime1-starttime1+”\nReplacing NaNs via 32bit pixel replacement time = "+endtime2-starttime2);
run(“Tile”);

Here is the result:

I can’t seem to upload the Tif image I used. You can just cut it out of the screenshot if you want to run the code on the same image.

Any ideas on what’s happening here would be appreciated.

Thanks
Ron DeSpain