Login  Register

Re: How to read 'raw' data as 32 bit unsigned in Java

Posted by Kenneth Sloan-2 on Feb 12, 2019; 11:12pm
URL: http://imagej.273.s1.nabble.com/How-to-read-raw-data-as-32-bit-unsigned-in-Java-tp5021772p5021781.html

Once you have a ShortProcessor, you can convert directly to a ColorProcessor using:

        ColorProcessor cp = sp.convertToColorProcessor();

I am not sure how the 16-bit values are converted to 8+8+8 RGB.  You may have to call

        sp.setMinAndMax(min,max);

before the conversion.

But...it looks as if the safest route might be:

        sp.setMinAndMax(min,max); // in case you want to adjust these
        ColorProcessor cp = sp.convertToByteProcessor(true).convertToRGB()

I'm unclear on the difference between convertToRGB() and convertToColorProcessor.  From the documentation:

public ColorProcessor <https://imagej.nih.gov/ij/developer/api/ij/process/ColorProcessor.html> convertToColorProcessor()
Returns an RGB version of this image as a ColorProcessor.

public ImageProcessor <https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html> convertToRGB()
Returns an RGB version of this image as a ColorProcessor.

The only difference is in the declared type of the returned processor.  Both are actually "ColorProcessor", but notice
that "convertToRGB()" returns an "ImageProcessor" (which just happens to be a "ColorProcessor".

Can someone explain the reason for this apparent duplication?

--
Kenneth Sloan
[hidden email]
Vision is the art of seeing what is invisible to others.





> On Feb 12, 2019, at 16:21, Robert Lockwood <[hidden email]> wrote:
>
> Thanks, Kenneth, this is a stand-alone program to detect adjacent pixels
> that have t:
> he same values and save the probably converted data as grayscale
> with the detected pixels in color.
>
> Here is the code I have now, compiles and runs but unfinished
>
>            // read raw image file
>            byte[] bytes = Files.toByteArray(dFile);
>            // represent as integers
>            IntBuffer rawIntImage = ByteBuffer.wrap(bytes).asIntBuffer();
>
>            // set up for data using imageJ
>            final ImagePlus imp = IJ.createImage(dFile.getName(), "16-bit",
>                    NCOLS, NROWS, 1);
>            final ShortProcessor sp = (ShortProcessor) imp.getProcessor();
>            final short[] shortImage = (short[]) sp.getPixels();
>            int index = 0;
>            while(rawIntImage.hasRemaining()) {
>                shortImage[index++] = (short) rawIntImage.get();
>            }
>            // sp.convertToByte(true).convertToRGB(); // What is returned
> here?
>
> I need "IntBuffer rawIntImage" to use to detect the adjacent duplicate
> pixels
> I'm assuming that 'convertToByte' will do the brightness and contrast
> mapping returning a ByteProcessor, is that correct?  Then I need to convert
> to RGB ?
>
>
> On Tue, Feb 12, 2019 at 1:19 PM Kenneth Sloan <[hidden email]>
> wrote:
>
>> Ah...if the data are really 16-bit, then my recommendation is to
>> import the image as a 32-bit float, apply Brightness/Contrast,
>> and use an OVERLAY to highlight the problem pixels.
>>
>> But, if you really want RGB, import as 32-bit, adjust,
>> and use Image->Type->RGB and you are done.
>>
>> Note that this loses precision (but, you can't see much more than
>> 8-bits on the screen anyway).
>>
>> You also lose access to the actual original pixel values - but
>> perhaps that's not important.
>>
>> I do this routinely with data that claim to be 32-bit floats in the
>> range [0.0..1.0).  These are essentially 24-bit unsigned integers.
>>
>> It looks like there is no reason for you to import a byte array
>> and twiddle bits to construct ints.  Fiji will happily import
>> the image as 32-bit float, adjust brightness/contrast, and convert
>> to RGB (if that's what you want).
>>
>> Is your code to find and highlight problem pixels written as a
>> Fiji plugin, or as a stand-alone Java program?
>>
>>
>> --
>> Kenneth Sloan
>> [hidden email]
>> Vision is the art of seeing what is invisible to others.
>>
>>
>>
>>
>>
>>> On Feb 12, 2019, at 14:48, Robert Lockwood <[hidden email]> wrote:
>>>
>>> When I look at the imported images in Fiji I apply Brightness/Contrast
>> with
>>> auto for a decent image.
>>>
>>> If I can do the same thing in Java and then convert to RGB I can then
>>> manipulate the pixels I've identified by my comparison code.
>>>
>>> BTW the values in my 32 bit first came from the camera as defined as C
>>> unsigned shorts so all the values are less than 64K so I can extract the
>>> Java short values easily.
>>>
>>> On Tue, Feb 12, 2019 at 11:20 AM Kenneth Sloan <[hidden email]>
>>> wrote:
>>>
>>>> If you do this in Java, I think there are a couple of workarounds.
>>>>
>>>> Here's one idea: Since you already can "process these data as ints", you
>>>> should be able to create your own 8-bit RGB image.  Of course, you only
>>>> get 8-bits of gray scale.
>>>>
>>>> Here's another idea: you should be able to import the image as a 32-bit
>>>> float image.  If there is non-zero data in the upper 8 bits, the image
>>>> will look
>>>> very strange, but at least you'll have a 32-bit array.  Next, take each
>>>> 32-bit float pixel value and use Float.floatToRawIntBits to get
>>>> your 32-bit integer values.
>>>>
>>>> Since you can already create the int values from your byte array, I
>> would
>>>> start
>>>> with that idea.
>>>>
>>>> Be careful about signed/unsigned.
>>>>
>>>> Finally, I would consider creating a 24-bit integer gray-scale value,
>> and
>>>> using
>>>> that as a 32-bit float (using Float.intBitsToFloat).  This gives you a
>>>> float image
>>>> where the values are between 0.0 and 1.0.  You can then use an Overlay
>> to
>>>> highlight
>>>> the problem pixels.  Use either idea above to get a 32-bit unsigned
>> value,
>>>> and
>>>> scale it to 24-bits.  Convert that to a float, and store it in a 32-bit
>>>> float image.
>>>>
>>>> Or, simply create a 16-bit integer gray scale image, and use an Overlay.
>>>>
>>>> Your choice may depend on what you know about the range of values.  The
>>>> advantage of
>>>> my 24-bit version above is that you have a bit more flexibility in
>>>> dynamically adjusting
>>>> the range of displayed gray levels.  The disadvantage is that the
>> numbers
>>>> will all
>>>> be presented as (0.0..1.0) instead of [0..65535] (for the 16-bit
>> version)
>>>>
>>>> --
>>>> Kenneth Sloan
>>>> [hidden email]
>>>> Vision is the art of seeing what is invisible to others.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>> On Feb 12, 2019, at 12:37, Herbie <[hidden email]> wrote:
>>>>>
>>>>> Good day,
>>>>>
>>>>> ImageJ doesn't support 32 bit integer gray scale images.
>>>>>
>>>>> Supported are 8bit and 16bit integer as well as 32bit float.
>> Furthermore
>>>> 24bit (3 X 8bit) RGB and index color 8bit.
>>>>>
>>>>> Regards
>>>>>
>>>>> Herbie
>>>>>
>>>>> :::::::::::::::::::::::::::::::::::::::::::::
>>>>> Am 12.02.19 um 19:15 schrieb Robert Lockwood:
>>>>>> Working with Java I have raw data files with 32 bit integer gray scale
>>>> data
>>>>>> which I read into a byte[] array.  I process these data as ints
>> looking
>>>> for
>>>>>> adjacent pixels that have the same value in order to debug a problem
>>>> with
>>>>>> the camera.
>>>>>> I'd like to create a scaled grayscale RGB from the original data so
>>>> that I
>>>>>> may color the detected adjacent pixels to allow us to detect patterns
>>>>>> visually but I don't understand how to create and populate a grayscale
>>>>>> integer ImageJ array and have not found an example by Google
>> searching.
>>>>>> How do I do this?
>>>>>> TIA
>>>>>> --
>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>
>>>>> --
>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>> --
>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html


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