Handling signed and unsigned 16-bit images

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

Handling signed and unsigned 16-bit images

Michael Doube
Hi all

After a bit of googling and hacking and tying myself in knots, I have to
ask the list how people write plugins that can elegantly handle both
signed and unsigned 16-bit images?

I had a play with http://rsbweb.nih.gov/ij/plugins/converter.html, and
will continue in this sort of direction unless there's a known better
way to do it.

Cheers

Mike
Reply | Threaded
Open this post in threaded view
|

Re: Handling signed and unsigned 16-bit images

Reinhard Mayr aka Czerwinski
Mike,

I once extended the AVIReader for a certain kind of 16bit AVIs (http://rsb.info.nih.gov/ij/plugins/download/AVI_Reader.java). Maybe you find something useful there.

As far as I remember, the major problem is that Java does not know unsigned data types.

Hth & all the best!

Reinhard.

-------- Original-Nachricht --------
> Datum: Tue, 24 Mar 2009 11:15:15 +0000
> Von: Michael Doube <[hidden email]>
> An: [hidden email]
> Betreff: Handling signed and unsigned 16-bit images

> Hi all
>
> After a bit of googling and hacking and tying myself in knots, I have to
> ask the list how people write plugins that can elegantly handle both
> signed and unsigned 16-bit images?
>
> I had a play with http://rsbweb.nih.gov/ij/plugins/converter.html, and
> will continue in this sort of direction unless there's a known better
> way to do it.
>
> Cheers
>
> Mike

--
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger01
Reply | Threaded
Open this post in threaded view
|

Re: Handling signed and unsigned 16-bit images

Burger Wilhelm
In reply to this post by Michael Doube
Right, Java has no unsigned types - but it is only a matter of a few bit operations to treat 16-bit words as either signed (default) or unsigned. However, I don't think there is any way to mark a ShortProcessor as "signed", so a plugin cannot distinguish between unsigned and signed images (unless you make assumptions).

--Wilhelm

 


> -----Original Message-----
> From: ImageJ Interest Group [mailto:[hidden email]] On
> Behalf Of Reinhard Mayr aka Czerwinski
> Sent: Tuesday, March 24, 2009 1:43 PM
> To: [hidden email]
> Subject: Re: Handling signed and unsigned 16-bit images
>
> Mike,
>
> I once extended the AVIReader for a certain kind of 16bit
> AVIs
> (http://rsb.info.nih.gov/ij/plugins/download/AVI_Reader.java).
>  Maybe you find something useful there.
>
> As far as I remember, the major problem is that Java does not
> know unsigned data types.
>
> Hth & all the best!
>
> Reinhard.
>
> -------- Original-Nachricht --------
> > Datum: Tue, 24 Mar 2009 11:15:15 +0000
> > Von: Michael Doube <[hidden email]>
> > An: [hidden email]
> > Betreff: Handling signed and unsigned 16-bit images
>
> > Hi all
> >
> > After a bit of googling and hacking and tying myself in
> knots, I have to
> > ask the list how people write plugins that can elegantly
> handle both
> > signed and unsigned 16-bit images?
> >
> > I had a play with
> http://rsbweb.nih.gov/ij/plugins/converter.html, and
> > will continue in this sort of direction unless there's a
> known better
> > way to do it.
> >
> > Cheers
> >
> > Mike
>
> --
> Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s
> mit allen: http://www.gmx.net/de/go/multimessenger01
>
Reply | Threaded
Open this post in threaded view
|

Re: Handling signed and unsigned 16-bit images

Michael Schmid
Hi Mike,

it depends what you want.

In ImageJ, 16-bit images are taken as unsigned by default; thus all  
reading of pixel data requires code like this:
   int value32bit = pixels[pixelPointer]&0xffff;
where
   short[] pixels = (short[])ImageProcessor.getPixels();

Signed 16-bit images are simply unsigned data with a calibration  
table that maps pixel value 0 to -32768 and
32768 to 0. To simplify the code, actually any calibration table that  
maps 0 to -32768 (irrespective of the further values) is taken as an  
indication of signed 16-bit data.

For most filter operations, it makes no difference whether the data  
are signed or unsigned.
For math operations such as multiply, the operation depends on the  
calibration table as stated above.

For analysis of pixel values, you can use  
ImageProcessor.getPixelValue; it gives the calibrated values and thus  
you get the correct values for signed data. Also  
ImageProcessor.putPixelValue works with both signed and unsigned 16-
bit images.

When writing a PluginFilter, ImageJ will automatically take care that  
an ImageProcessor gets the correct calibration from its ImagePlus. In  
a Plugin, you may have to care about this separately, especially when  
processing stacks.

The CONVERT_TO_FLOAT flag of a PlugInFilter does not take calibration  
into account; thus it always takes the data as unsigned 16 bit.

Hope this helps,

Michael
________________________________________________________________

On 24 Mar 2009, at 14:01, Burger Wilhelm wrote:

> Right, Java has no unsigned types - but it is only a matter of a  
> few bit operations to treat 16-bit words as either signed (default)  
> or unsigned. However, I don't think there is any way to mark a  
> ShortProcessor as "signed", so a plugin cannot distinguish between  
> unsigned and signed images (unless you make assumptions).
>
> --Wilhelm
>
>
>
>
>> -----Original Message-----
>> From: ImageJ Interest Group [mailto:[hidden email]] On
>> Behalf Of Reinhard Mayr aka Czerwinski
>> Sent: Tuesday, March 24, 2009 1:43 PM
>> To: [hidden email]
>> Subject: Re: Handling signed and unsigned 16-bit images
>>
>> Mike,
>>
>> I once extended the AVIReader for a certain kind of 16bit
>> AVIs
>> (http://rsb.info.nih.gov/ij/plugins/download/AVI_Reader.java).
>>  Maybe you find something useful there.
>>
>> As far as I remember, the major problem is that Java does not
>> know unsigned data types.
>>
>> Hth & all the best!
>>
>> Reinhard.
>>
>> -------- Original-Nachricht --------
>>> Datum: Tue, 24 Mar 2009 11:15:15 +0000
>>> Von: Michael Doube <[hidden email]>
>>> An: [hidden email]
>>> Betreff: Handling signed and unsigned 16-bit images
>>
>>> Hi all
>>>
>>> After a bit of googling and hacking and tying myself in
>> knots, I have to
>>> ask the list how people write plugins that can elegantly
>> handle both
>>> signed and unsigned 16-bit images?
>>>
>>> I had a play with
>> http://rsbweb.nih.gov/ij/plugins/converter.html, and
>>> will continue in this sort of direction unless there's a
>> known better
>>> way to do it.
>>>
>>> Cheers
>>>
>>> Mike
>>
>> --
>> Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s
>> mit allen: http://www.gmx.net/de/go/multimessenger01
>>
Reply | Threaded
Open this post in threaded view
|

Re: Handling signed and unsigned 16-bit images

Michael Doube
Thanks Michael,

This is helpful.  I am comparing a pixel value to min/max cutoffs and
also applying a pixel value -> apparent density calibration and getting
thoroughly confused about the actual values that are being compared and
converted.

While accessing pixel values directly from an array should be faster:

short[] pixels = (short[])ImageStack.getPixels(sliceNumber);
int value32bit = pixels[pixelPointer]&0xffff;

Perhaps using
ImageProcessor sliceProcessor = ImageStack.getProcessor(sliceNumber);
int value32bit = sliceProcessor.getPixelValue(x,y);

Would be more convenient, since value32bit will be a calibrated value?

Mike

Michael Schmid wrote:

> Hi Mike,
>
> it depends what you want.
>
> In ImageJ, 16-bit images are taken as unsigned by default; thus all  
> reading of pixel data requires code like this:
>    int value32bit = pixels[pixelPointer]&0xffff;
> where
>    short[] pixels = (short[])ImageProcessor.getPixels();
>
> Signed 16-bit images are simply unsigned data with a calibration  
> table that maps pixel value 0 to -32768 and
> 32768 to 0. To simplify the code, actually any calibration table that  
> maps 0 to -32768 (irrespective of the further values) is taken as an  
> indication of signed 16-bit data.
>
> For most filter operations, it makes no difference whether the data  
> are signed or unsigned.
> For math operations such as multiply, the operation depends on the  
> calibration table as stated above.
>
> For analysis of pixel values, you can use  
> ImageProcessor.getPixelValue; it gives the calibrated values and thus  
> you get the correct values for signed data. Also  
> ImageProcessor.putPixelValue works with both signed and unsigned 16-
> bit images.
>
> When writing a PluginFilter, ImageJ will automatically take care that  
> an ImageProcessor gets the correct calibration from its ImagePlus. In  
> a Plugin, you may have to care about this separately, especially when  
> processing stacks.
>
> The CONVERT_TO_FLOAT flag of a PlugInFilter does not take calibration  
> into account; thus it always takes the data as unsigned 16 bit.
>
> Hope this helps,
>
> Michael
> ________________________________________________________________
>
> On 24 Mar 2009, at 14:01, Burger Wilhelm wrote:
>
>> Right, Java has no unsigned types - but it is only a matter of a  
>> few bit operations to treat 16-bit words as either signed (default)  
>> or unsigned. However, I don't think there is any way to mark a  
>> ShortProcessor as "signed", so a plugin cannot distinguish between  
>> unsigned and signed images (unless you make assumptions).
>>
>> --Wilhelm
>>
>>
>>
>>
>>> -----Original Message-----
>>> From: ImageJ Interest Group [mailto:[hidden email]] On
>>> Behalf Of Reinhard Mayr aka Czerwinski
>>> Sent: Tuesday, March 24, 2009 1:43 PM
>>> To: [hidden email]
>>> Subject: Re: Handling signed and unsigned 16-bit images
>>>
>>> Mike,
>>>
>>> I once extended the AVIReader for a certain kind of 16bit
>>> AVIs
>>> (http://rsb.info.nih.gov/ij/plugins/download/AVI_Reader.java).
>>>  Maybe you find something useful there.
>>>
>>> As far as I remember, the major problem is that Java does not
>>> know unsigned data types.
>>>
>>> Hth & all the best!
>>>
>>> Reinhard.
>>>
>>> -------- Original-Nachricht --------
>>>> Datum: Tue, 24 Mar 2009 11:15:15 +0000
>>>> Von: Michael Doube <[hidden email]>
>>>> An: [hidden email]
>>>> Betreff: Handling signed and unsigned 16-bit images
>>>> Hi all
>>>>
>>>> After a bit of googling and hacking and tying myself in
>>> knots, I have to
>>>> ask the list how people write plugins that can elegantly
>>> handle both
>>>> signed and unsigned 16-bit images?
>>>>
>>>> I had a play with
>>> http://rsbweb.nih.gov/ij/plugins/converter.html, and
>>>> will continue in this sort of direction unless there's a
>>> known better
>>>> way to do it.
>>>>
>>>> Cheers
>>>>
>>>> Mike
>>> --
>>> Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s
>>> mit allen: http://www.gmx.net/de/go/multimessenger01
>>>

--
Dr Michael Doube  BPhil BVSc PhD MRCVS
Research Associate
Department of Bioengineering
Imperial College London
South Kensington Campus
London  SW7 2AZ
United Kingdom

Phone: +44 (0)20 7594 7426
Fax: +44 (0)20 7594 9817
Reply | Threaded
Open this post in threaded view
|

Re: Handling signed and unsigned 16-bit images

Michael Schmid
Hi Mike,

just two remarks:

getPixelValue is float, not int. It is the most convenient way of  
accessing calibrated values.

Accessing the pixels array is faster than getPixelValue, but you  
won't feel much of a difference unless you access each pixel many  
times (as, e.g., in a filter operation, where the output for each  
pixel is computed from the values of all of its neighbors).

Michael
________________________________________________________________

On 24 Mar 2009, at 18:47, Michael Doube wrote:

> Thanks Michael,
>
> This is helpful.  I am comparing a pixel value to min/max cutoffs  
> and also applying a pixel value -> apparent density calibration and  
> getting thoroughly confused about the actual values that are being  
> compared and converted.
>
> While accessing pixel values directly from an array should be faster:
>
> short[] pixels = (short[])ImageStack.getPixels(sliceNumber);
> int value32bit = pixels[pixelPointer]&0xffff;
>
> Perhaps using
> ImageProcessor sliceProcessor = ImageStack.getProcessor(sliceNumber);
> int value32bit = sliceProcessor.getPixelValue(x,y);
>
> Would be more convenient, since value32bit will be a calibrated value?
>
> Mike
>
> Michael Schmid wrote:
>> Hi Mike,
>> it depends what you want.
>> In ImageJ, 16-bit images are taken as unsigned by default; thus  
>> all  reading of pixel data requires code like this:
>>    int value32bit = pixels[pixelPointer]&0xffff;
>> where
>>    short[] pixels = (short[])ImageProcessor.getPixels();
>> Signed 16-bit images are simply unsigned data with a calibration  
>> table that maps pixel value 0 to -32768 and
>> 32768 to 0. To simplify the code, actually any calibration table  
>> that  maps 0 to -32768 (irrespective of the further values) is  
>> taken as an  indication of signed 16-bit data.
>> For most filter operations, it makes no difference whether the  
>> data  are signed or unsigned.
>> For math operations such as multiply, the operation depends on  
>> the  calibration table as stated above.
>> For analysis of pixel values, you can use  
>> ImageProcessor.getPixelValue; it gives the calibrated values and  
>> thus  you get the correct values for signed data. Also  
>> ImageProcessor.putPixelValue works with both signed and unsigned  
>> 16- bit images.
>> When writing a PluginFilter, ImageJ will automatically take care  
>> that  an ImageProcessor gets the correct calibration from its  
>> ImagePlus. In  a Plugin, you may have to care about this  
>> separately, especially when  processing stacks.
>> The CONVERT_TO_FLOAT flag of a PlugInFilter does not take  
>> calibration  into account; thus it always takes the data as  
>> unsigned 16 bit.
>> Hope this helps,
>> Michael
>> ________________________________________________________________
>> On 24 Mar 2009, at 14:01, Burger Wilhelm wrote:
>>> Right, Java has no unsigned types - but it is only a matter of a  
>>> few bit operations to treat 16-bit words as either signed  
>>> (default)  or unsigned. However, I don't think there is any way  
>>> to mark a  ShortProcessor as "signed", so a plugin cannot  
>>> distinguish between  unsigned and signed images (unless you make  
>>> assumptions).
>>>
>>> --Wilhelm
>>>
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: ImageJ Interest Group [mailto:[hidden email]] On
>>>> Behalf Of Reinhard Mayr aka Czerwinski
>>>> Sent: Tuesday, March 24, 2009 1:43 PM
>>>> To: [hidden email]
>>>> Subject: Re: Handling signed and unsigned 16-bit images
>>>>
>>>> Mike,
>>>>
>>>> I once extended the AVIReader for a certain kind of 16bit
>>>> AVIs
>>>> (http://rsb.info.nih.gov/ij/plugins/download/AVI_Reader.java).
>>>>  Maybe you find something useful there.
>>>>
>>>> As far as I remember, the major problem is that Java does not
>>>> know unsigned data types.
>>>>
>>>> Hth & all the best!
>>>>
>>>> Reinhard.
>>>>
>>>> -------- Original-Nachricht --------
>>>>> Datum: Tue, 24 Mar 2009 11:15:15 +0000
>>>>> Von: Michael Doube <[hidden email]>
>>>>> An: [hidden email]
>>>>> Betreff: Handling signed and unsigned 16-bit images
>>>>> Hi all
>>>>>
>>>>> After a bit of googling and hacking and tying myself in
>>>> knots, I have to
>>>>> ask the list how people write plugins that can elegantly
>>>> handle both
>>>>> signed and unsigned 16-bit images?
>>>>>
>>>>> I had a play with
>>>> http://rsbweb.nih.gov/ij/plugins/converter.html, and
>>>>> will continue in this sort of direction unless there's a
>>>> known better
>>>>> way to do it.
>>>>>
>>>>> Cheers
>>>>>
>>>>> Mike
>>>> --
>>>> Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s
>>>> mit allen: http://www.gmx.net/de/go/multimessenger01
>>>>
>
> --
> Dr Michael Doube  BPhil BVSc PhD MRCVS
> Research Associate
> Department of Bioengineering
> Imperial College London
> South Kensington Campus
> London  SW7 2AZ
> United Kingdom
>
> Phone: +44 (0)20 7594 7426
> Fax: +44 (0)20 7594 9817