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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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
Reply | Threaded
Open this post in threaded view
|

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

Herbie
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
Reply | Threaded
Open this post in threaded view
|

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

Kenneth Sloan-2
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
Reply | Threaded
Open this post in threaded view
|

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

Michael Schmid
In reply to this post by Robert Lockwood
Hi Robert,

ImageJ can import 32-bit images; it opens them as 32-bit floating point
(which results in some loss of accuracy for high pixel values). You can
then apply a color LUT of your choice or any other processing you like.

Use File>Import>Raw or the corresponding IJ.run command (Use the Macro
Recorder in 'Java' mode).

Michael
________________________________________________________________


On 2019-02-12 19:15, Robert Lockwood wrote:

> 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
Reply | Threaded
Open this post in threaded view
|

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

Robert Lockwood
In reply to this post by Kenneth Sloan-2
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
Reply | Threaded
Open this post in threaded view
|

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

Kenneth Sloan-2
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
Reply | Threaded
Open this post in threaded view
|

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

Robert Lockwood
Thanks, Kenneth, this is a stand-alone program to detect adjacent pixels
that have the 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
Reply | Threaded
Open this post in threaded view
|

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

Kenneth Sloan-2
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
Reply | Threaded
Open this post in threaded view
|

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

Robert Lockwood
OK, I'm soldiering on...
My IDE tells me I need a cast:
        ColorProcessor cp = (ColorProcessor)
sp.convertToByteProcessor(true).convertToRGB()
sp.getMin() & sp.getMax() return reasonable values.
cp.get(500) for both .convertToRGB() and convertToColorProcessor() return
negative values. Apparently there are 3 color components so there's no
alpha.  Does this mean that the data are 24 bit?




On Tue, Feb 12, 2019 at 3:12 PM Kenneth Sloan <[hidden email]>
wrote:

> 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
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

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

Kenneth Sloan-2
You started with a scalar (float) image.  You converted it to an 8-bit integer image.
The convertToRGB() simply replicates the 8-bit byte for the R,G,B channels and sets A==0;

By the time you converted to RGB, you had only 8 bits.

get(500) uses ImageProcessor.get() and returns an int.  I always treat images
as 2D and avoid fetching pixels by pretending to know how they are laid out
in memory - but I presume that get() returns the bits representing RGBA as an int.
I suppose stepping through a 1D array is "faster", but (to my taste) that's a false economy.

A negative value indicates that the R value is > 127.  Since it's a grayscale image, that
makes R=G=B > 127, so "brighter than middle gray".

None of this says anything about how many bits you started with.  If you want to know
the range of values in the original data, I recommend that you compute that yourself while
processing the original 32 bit ints.

How did you end up creating the ORIGINAL image - did you import it as a FloatProcessor, or
did you build your byte array and construct 32 bit ints?  

For absolute control, I would use your byte array methods to construct pixel values, determine
the range of actual values, and then create a (scaled, if necessary) 16-bit ShortProcessor.

I would then set min and max, and convert directly from the ShortProcessor to a ColorProcessor.

For ease of programming, I would try to import the original image as a 32-bit float image, and
then use get().  I'm guessing (because I don't even do this) that get() will return the actual 32-bits
used to represent the Float.  But, I could be wrong about that.  All of this simply avoids the bit-twiddling
you are doing with the byte array.  I would then proceed as above: determine range, create a (possibly scaled)
16-bit ShortProcessor, and convert to RGB.  I would probably only use the "import as Float" method if I
were *certain* that the raw data was no bigger than 24 bits.

The acid test is to display the image.  I might also create a test suite consisting of (small) 32-bit
images with known values testing the various boundaries - say 0xffffffff, and 0x7fffffff, and 0x00ffffff, and 0x0000ffff, for starters.  I would start with images that had constant values (one image for each of the above values), and then
images consisting of ramps from 0 to each of the above values.  Finally, ramps that start a bit higher than 0, to test
your setting of min/max.  That's 12 test images in all.

Have fun!

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




 

> On Feb 12, 2019, at 18:22, Robert Lockwood <[hidden email]> wrote:
>
> OK, I'm soldiering on...
> My IDE tells me I need a cast:
>        ColorProcessor cp = (ColorProcessor)
> sp.convertToByteProcessor(true).convertToRGB()
> sp.getMin() & sp.getMax() return reasonable values.
> cp.get(500) for both .convertToRGB() and convertToColorProcessor() return
> negative values. Apparently there are 3 color components so there's no
> alpha.  Does this mean that the data are 24 bit?
>
>
>
>
> On Tue, Feb 12, 2019 at 3:12 PM Kenneth Sloan <[hidden email] <mailto:[hidden email]>>
> wrote:
>
>> 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 <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 <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 <http://imagej.nih.gov/ij/list.html>
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html <http://imagej.nih.gov/ij/list.html>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

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

Curtis Rueden
In reply to this post by Robert Lockwood
Hi all,

> ImageJ doesn't support 32 bit integer gray scale images.

It is more precise to write "ImageJ1 doesn't support 32-bit integer
grayscale images."

ImageJ2 does support them.

Here is Groovy code illustrating it:

--snip--
v = Integer.MAX_VALUE
int[] values = [
    v, v - 1, v - 2, v / 4,
    v / 4 - 3, v / 8 - 5, v / 3, v / 2 + 5,
    v / 2 + 3, v / 2 + 7, v / 2 + 11, v / 2 + 13
]
img = net.imglib2.img.array.ArrayImgs.ints(values, 4, 3)

access = img.randomAccess()
for (y=0; y<3; y++) {
    for (x=0; x<4; x++) {
        access.setPosition(x, 0)
        access.setPosition(y, 1)
        println("($x, $y) = ${access.get()} (array
value=${values[4*y+x]})")
    }
}
--snap--

Regards,
Curtis

--
Curtis Rueden
LOCI software architect - https://loci.wisc.edu/software
ImageJ2 lead, Fiji maintainer - https://imagej.net/User:Rueden
Have you tried the Image.sc Forum? https://forum.image.sc/



On Tue, Feb 12, 2019 at 12:38 PM 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
Reply | Threaded
Open this post in threaded view
|

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

Robert Lockwood
In reply to this post by Kenneth Sloan-2
Thanks, Kenneth, Herby, Michael, I've not worked with anything other than
16 bit unsigned images as that's our native data.  I've been able to create
the image that I wanted with one problem.  I've replaced the second of the
adjacent pixels with the same value with a green pixel in the RGB image I
created from my 16 bit data but some are green and some are white!

I'll need to save a file with the unexamined RGB data next, I guess, to see
if its a processing artifact.


On Tue, Feb 12, 2019 at 7:07 PM Kenneth Sloan <[hidden email]>
wrote:

> You started with a scalar (float) image.  You converted it to an 8-bit
> integer image.
> The convertToRGB() simply replicates the 8-bit byte for the R,G,B channels
> and sets A==0;
>
> By the time you converted to RGB, you had only 8 bits.
>
> get(500) uses ImageProcessor.get() and returns an int.  I always treat
> images
> as 2D and avoid fetching pixels by pretending to know how they are laid out
> in memory - but I presume that get() returns the bits representing RGBA as
> an int.
> I suppose stepping through a 1D array is "faster", but (to my taste)
> that's a false economy.
>
> A negative value indicates that the R value is > 127.  Since it's a
> grayscale image, that
> makes R=G=B > 127, so "brighter than middle gray".
>
> None of this says anything about how many bits you started with.  If you
> want to know
> the range of values in the original data, I recommend that you compute
> that yourself while
> processing the original 32 bit ints.
>
> How did you end up creating the ORIGINAL image - did you import it as a
> FloatProcessor, or
> did you build your byte array and construct 32 bit ints?
>
> For absolute control, I would use your byte array methods to construct
> pixel values, determine
> the range of actual values, and then create a (scaled, if necessary)
> 16-bit ShortProcessor.
>
> I would then set min and max, and convert directly from the ShortProcessor
> to a ColorProcessor.
>
> For ease of programming, I would try to import the original image as a
> 32-bit float image, and
> then use get().  I'm guessing (because I don't even do this) that get()
> will return the actual 32-bits
> used to represent the Float.  But, I could be wrong about that.  All of
> this simply avoids the bit-twiddling
> you are doing with the byte array.  I would then proceed as above:
> determine range, create a (possibly scaled)
> 16-bit ShortProcessor, and convert to RGB.  I would probably only use the
> "import as Float" method if I
> were *certain* that the raw data was no bigger than 24 bits.
>
> The acid test is to display the image.  I might also create a test suite
> consisting of (small) 32-bit
> images with known values testing the various boundaries - say 0xffffffff,
> and 0x7fffffff, and 0x00ffffff, and 0x0000ffff, for starters.  I would
> start with images that had constant values (one image for each of the above
> values), and then
> images consisting of ramps from 0 to each of the above values.  Finally,
> ramps that start a bit higher than 0, to test
> your setting of min/max.  That's 12 test images in all.
>
> Have fun!
>
> --
> Kenneth Sloan
> [hidden email]
> Vision is the art of seeing what is invisible to others.
>
>
>
>
>
>
> On Feb 12, 2019, at 18:22, Robert Lockwood <[hidden email]> wrote:
>
> OK, I'm soldiering on...
> My IDE tells me I need a cast:
>        ColorProcessor cp = (ColorProcessor)
> sp.convertToByteProcessor(true).convertToRGB()
> sp.getMin() & sp.getMax() return reasonable values.
> cp.get(500) for both .convertToRGB() and convertToColorProcessor() return
> negative values. Apparently there are 3 color components so there's no
> alpha.  Does this mean that the data are 24 bit?
>
>
>
>
> On Tue, Feb 12, 2019 at 3:12 PM Kenneth Sloan <[hidden email]>
> wrote:
>
> 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
>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
>
>

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