Non-negative OD calibration functions



Hello everybody,

I must calibrate unirradiated fuel plates digital radiographies for uranium density. They are surrounded by an aluminum frame which should obviously show up as zero uranium density; however, the only function that seems to coerce undesireable negative values to zero is “Rodbard (NIH)”, while I would like to use something like “y=a+b*ln(x-c)” instead and still get zero results for the two brighter areas of the image. How can I coerce negative density values to zero?

I’m attaching a downsized, downscaled (8-bit) version of the original file showing the aluminum frame around the fuel core, lying on the empty glass bed of the scanner around it. There are grossly three levels of grays, but all the information needed must be extracted from the large central dark area. Original file is in 16-bit format, though scanner resolution is only 12-bit. Calibrated densities must show zero for both of the two brighter

areas (no negative values allowed).

I know ImageJ is aimed to medical and biological image analysis, but I’m getting surprisingly good results for this kind of quality control on fuel plate production at our institute by combining built-in tools with macro programming; some of our coleagues are overwhelmed.

Thank you for any help, and wish you a Happy New Year!

Flavio, from IPEN (Sao Paulo, Brazil).


You could preprocess and replace all negative values in your image with a macro function.

One easy function can be found in the ImageJ macro API:

changeValues(v1, v2, v3)


See also this older thread of the mailing list:


Dear Bio7,

I tried to use the function you suggested, but I noticed it is meant to affect uncalibrated pixel values, while I only want to change their calibrated values if they result negative.

In other words, I actually get negative values from calibrated values only, since their uncalibrated values are always positive (my original input files are simple16-bit monochrome images).

I discovered by trial and error that the only built-in calibration function that coerces negative calibrated values to zero is the “Rodbard (NIH Image)” function, and I still wonder how to get such behavior from other functions like “y=a+b*ln(x-c)”, for instance (I also found out that the built-in “Rodbard” (straight) function does not coerce negative calibrated values to zero).

By using the menu “Measure” tool I get vital results from ROI selected image areas, so I’m afraid it might not be practical to process individual pixels by using the “calibrate(value)” macro function to rule out negative calibrated values from the sample.

For now, “Rodbard (NIH Image)” remains the only useable function for my application. Despite of being very flexible and versatile, I still wonder if I could do any better.

Thank you for your help,

Flavio, from IPEN (Sao Paulo, Brazil)


You can,e.g., apply a calibrated function to all selected pixels in a ROI selection, summarize them with custom code,see:

Use the calibrate function to get the calibrated values for each pixels:

Or even easier you can apply your custom calibration function with the image math functions to convert an image (or copy) to the calibrated values available in the Process->Math->Macro menu.

Then convert the negative values and use the measure function on the now calibrated ROI’s (you can write a small macro to automatize this easily or use the macro recorder!).

Apropos here is a similar thread which also might be a help:


Well, that was edifying.

Converting the 16-bit image to the 32-bit format caused the previously calibrated value to be applied to each pixel. However, original (uncalibrated) 16-bit integer values are lost in the process.

Using the 32-bit image format as a container of the calibrated values indeed allows for programatically trimming off negative values using Mr. Perez approach of nested loops. I had not been able to find that 2009 thread before - thanks for bringing it to my attention!

Drawbacks (besides the previously mentioned loss of uncalibrated values):

  • Zero trimming took 12s of additional processing time on my PC;
  • Doubled the size of the original 16-bit file (from 33MB to 67MB);
  • More difficult visualization - ended up using a color LUT overlay;
  • Color overlay increased file size to 84M (16-bit) or 118M (32-bit).

Anyway, it was possible to do what I wanted: to trim off the zeros from the calibrated values without having to use “Rodbard (NIH)” - seemingly the only built-in function on ImageJ with such behavior. Many thanks!

Flavio, from IPEN (Sao Paulo, Brazil).