Login  Register

How to correct 32bits(RGB) images?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options Options
Embed post
Permalink
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

How to correct 32bits(RGB) images?

NatashaW
16 posts
Dear all,

I’m working on group of images and I need to correct them by using the correspondent flat-field frame.
My images are 32(RGB) and I split them and worked on every channel.
For example, in green channel I divided by flat-field green frame then multiplied by the mean value for the same flat-field frame. And I have 2 questions please:
1) When I convert them to float (rgbip.convertToFloat) I got very bright images.. I don’t know if my images             were damaged during the converting and if I can still work on them and get information from the pixels values?
2) When I worked only with byte (without converting to float) I get my images in the same contrast so can I apply this method or I’m going to lose many details during division?

Thank you so much for any help,
Best wishes,

Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: How to correct 32bits(RGB) images?

Michael Schmid
2136 posts
On 20 May 2010, at 15:22, NatashaW wrote:

> 1) When I convert them to float (rgbip.convertToFloat) I got very  
> bright
> images.. I don’t know if my images             were damaged during the
> converting and if I can still work on them and get information from  
> the
> pixels values?
> 2) When I worked only with byte (without converting to float) I get my
> images in the same contrast so can I apply this method or I’m going  
> to lose
> many details during division?

Hi Natasha,

ImageProcessor.convertToFloat does not damage anything; the reason  
for the different way it is displayed is autoscaling of Float images:  
if the data are, say, 1-120, 1 is displayed as black and 120 as  
white. For 8-bit images, by default, you have a display range of  
0-255, irrespective of the image data.
When you convert back to RGB, you should recover a reasonable  
brightness range unless you have 'scale conversions' true (this would  
take the full range of the float data for the 0-255 range of each 8-
bit color channel).

If you do more than one operation, you will have better precision  
when using float data, especially if you have some intermediate step  
where the data range becomes less than that of the original data.

For most cases, I would recommend the ImageProcessor.toFloat(int  
channelNumber, FloatProcessor fp) and setPixels(int channelNumber,  
FloatProcessor fp) methods - these do not any scaling and allow you  
to write a plugin that works on all types of images (gray and RGB):

//input:  ip1 and ip2
//output: ip1
FloatProcessor fp1 = null, fp2 = null;
for (int i=0; i<ip.getNChannels(); i++) {
     fp1 = ip1.toFloat(i, fp1);
     fp2 = ip2.toFloat(i, fp2);
     do_Some_Float_Operation(fp1, fp2);
     ip1.setPixels(i, fp1);
}

Michael
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: How to correct 32bits(RGB) images?

NatashaW
16 posts
Thank you it's more clear now, but I still have another question please:

-> I used before this instruction rgbG[i]&255 to eliminate the sign bit.
    Can I eliminate the sign bit and convert it to short at the same time by only writing:
    rgbG1=(short)rgbG[i]&0XFFFF  where rgbG[] is a byte array ?
    or It won't work and I should eliminate the sign bit first and then apply
    mageProcessor.toFloat(int channelNumber, FloatProcessor fp) as you explained before?

->And after the images are shifted now for example to [0 , 65535] shouldn't I ranging them again to [−32768 , 32767] to show them normally with imageJ?

Thank you,
Natasha
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: How to correct 32bits(RGB) images?

Michael Schmid
2136 posts
Hi Natasha,

> -> I used before this instruction rgbG[i]&255 to eliminate the sign  
> bit.
>     Can I eliminate the sign bit and convert it to short at the  
> same time by
> only writing:
>     rgbG1=(short)rgbG[i]&0XFFFF  where rgbG[] is a byte array ?
no, you would have to write
  int r = (rgb[i]&0xff0000)>>16;
  int g = (rgb[i]&0xff00)>>8;
  int b =  rgb[i]&0xff;

output data will be 0-255 for all 3 channels.

>     ImageProcessor.toFloat(int channelNumber, FloatProcessor fp)
that's an easy way if you do float calculations, and it has the  
advantage that you can write code that works with all types of images  
(gray&float), see my code outline in the last post on this subject.  
Again, you will get float data 0-255 for 8-bit and rbg images, and  
0-65535 for 16-bit images. Back conversion by ip.setPixels(t  
channelNumber, FloatProcessor fp) uses the same range (lower/higher  
float pixel values will be mapped to 0 or the maximum).

> ->And after the images are shifted now for example to [0 , 65535]  
> shouldn't
> I ranging them again to [−32768 , 32767] to show them normally  
> with imageJ?
hummm, it is not really clear what you refer to. 16-bit data in  
ImageJ are unsigned, 0-65535 by definition, but you can have a  
calibration that maps that range to signed short, [−32768, 32767],  
for readout of pixel values.

When converting 16-bit or float data to 8-bit grayscale or rgb it  
depends on whether 'scale conversions' is true; if it is true, the  
current display (usually min-max of data) range is mapped to 0-255,  
if false, only the 0-255 range of short (float) data is used and  
becomes 0-255 of the 8-bit data (in that case you won't get better  
resolution by using 16 bits). This is fundamentally different from  
Photoshop, where the highest value of 16-bit data is read out as  
'255', and 16-bit data have the same range as 8-bit data, but better  
resolution.

Hope this helps,

Michael