Login  Register

Re: macro: convert calibrated value to raw pixel value?

Posted by Michael Schmid on Nov 11, 2019; 11:36am
URL: http://imagej.273.s1.nabble.com/macro-convert-calibrated-value-to-raw-pixel-value-tp5022651p5022654.html

Hi Kenneth,

it might be easier to duplicate the image, then use a series of
changeValues macro commands on the copy
   https://imagej.nih.gov/ij/developer/macro/functions.html#changeValues

If you input image is not a 32-bit (floating point) image but a
calibrated 8-bit or 16-bit image, convert it to 32 bits.

If there is an overlap between input and output values such as for the
value of 0 in your case (which on the output stands input values < 0),
you could first assign -1 to negative values, e.g.
   changeValues(-1e100,-1e-100, -1);
and at the end convert all -1 values to 0.

Finally, convert to 8 bits with "Scale when converting" in the
Conversion Options off. Or set the display range to 0-255 before
converting to 8 bits, then the "Scale when converting" does not hurt.

Note that changeValues accepts double-precision arguments, but 32-bit
images have values between roughly -34e38 and +34e38, so a value like
-1e100 is guaranteed to be more negative than any 32-bit number that can
occur. Similarly, -1e-100 is more negative than 0, but more positive
than any 32-bit number (cannot be closer to 0 than +/-1.4e-45).


Michael
________________________________________________________________
On 11.11.19 04:31, Kenneth Sloan wrote:

> I decided to learn a bit about the macro language (usually I write everything in Java).
>
> To start with, I thought I would write something simple.  Note that this is an exercise in
> techniques.
>
> I've hit a snag. I was trying to convert a calibrated 16-bit image to an 8-bit version, by processing it
> pixel-by-pixel.  Motivated by a previous question here, I wanted to set all pixels < 0.0 to 0,
> all pixels in  [0.0,10.0) to 50, those in [10.0, 20.0) to 100 ....etc.  Finally, all pixels with calibrated
> values > 40.0 should be set to 255.
>
> First, I tried going from a source image to a target image.  But...this seemed painfully slow because of the need(?)
> to constantly selectImage() on every getPixel() and putPixel().
>
> So...I switched to doing it in place.  This was speedy enough, but I ran into an issue with calibration.
>
> To categorize the pixels, I wanted calibrated values.  OK - I found getValue(x,y) and that was fine.  But...now
> I need to WRITE a calibrated value.  I can't find a function to do that.  putPixel(x,y,value) seems to accept raw pixel values.
> I found a method to convert raw pixel values to calibrated values, but not the other way around.
>
> Below is the current state of my floundering.  All hints gratefully accepted.  But please - don't try to tell me how to
> perform the high-level task easier.  It's just a warm-up exercise to become familiar with all the tools.
>
> Note that I have commented out some lines at the end - these show what I intend to do eventually.  But, right now I can't get correct calibrated values written to the image.
>
> I would also be interested in a reasonable way to do this without modifying (or copying) the original source image).  It seems to me to be cleaner to write the new pixels to a new target image.  But, that appears to be r e a l l y   s l o w.  (or, I don' know how to do it correctly)
>
> Be kind...
> ====================================================================================
> function sixBins(pixelIn){
>   if(pixelIn <=  0.0)
>     pixelOut = 0*5;
>   else if(pixelIn <= 10.0)
>       pixelOut = 10*5;
>   else if(pixelIn <= 20.0)
>       pixelOut = 20*5;
>   else if(pixelIn <= 30.0)
>       pixelOut = 30*5;
>   else if(pixelIn <= 40.0)
>     pixelOut = 40*5;
>   else if(pixelIn > 40.0)
>       pixelOut =  255.0;
>   return pixelOut;
>   }
>
> orig = getImageID();
> title = getTitle();
> w = getWidth();
> h = getHeight();
>
> print(title + " is " + w + "x" + h);
>
> for(row=0;row<h;row++){
>   for(col=0;col<w;col++) {
>     pixelIn = getValue(col,row);  // gives correct calibrated values!
>     pixelOut = sixBins(pixelIn);  // appears to work fine
>     setPixel(col,row,pixelOut);   // does not work if the image is 16-bit calibrated
>     print(pixelIn + " -> " + pixelOut); // really verbose debugging
>   }
> }
>  
> run("Histogram");
> // selectImage(orig);
> // setMinAndMax(0,255);
> // run("8-bit");
> // selectImage(orig);
> // run("Histogram");
> ====================================================================================
> --
> Kenneth Sloan
> [hidden email]
> Vision is the art of seeing what is invisible to others.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html