[Insight-users] Managing conversion of pixel types during file read

Luis Ibanez luis.ibanez at kitware.com
Thu, 15 Apr 2004 16:37:11 -0400


Hi Zach,

This may sound like a lazy solution (probably because it is :-)

but,

Why don't you instantiate the ImageFileReader using a  float
pixel type ?

This will have enough dynamic range for reading both 8 and 16
bits images signed/unsigned. Then you can use the Rescale
IntensityImageFilter in order to convert the intensity of
your images.

The ImageFileReader only performs casting. It doesn't rescale
intensities at all. So, the intensity range of your 8bits image
will be preserved if you read it with a ImageFileReader instantiated
for shorts or floats.  The RescaleIntensityImageFilter computes the
minimum and maximum values of your original image and transform
the intensity scale in order to match your selections of output
minimum/maximum values.


Performing filtering inside the readers sounds like a risky
operation,... over time you could imagine requests for converting
almost any ITK filter into a 'reading' option, and that's probably
not a good thing...

Note that you can query the ImageFileReader in order to get the
"Original" pixel type of the image file.  This must be done
after you call Update() in the ImageFileReader, since previous
to that, there may not be any ImageIO object associated with
the ImageFileReader.

You could invoke the:

       reader->GetImageIO()->GetPixelType()

For the signature of the GetPixelType() method please look
at the documentation of the ImageIOBase class

http://www.itk.org/Insight/Doxygen/html/classitk_1_1ImageIOBase.html



Regards,



    Luis



----------------------
Zachary Pincus wrote:

> Luis,
> 
> As far as I can tell, once I have read in an image, there is no way to 
> learn what the original dynamic range of the image *type* was. 
> Basically, the idea is that I want to read in heterogeneous image types, 
> and then compress the dynamic range of that *type*, whatever it is, to 
> [0, 1].
> 
> Specifically, the steps for this are:
> Read in an image that's stored on disk as k bits per pixel
> Convert it to a float
> Rescale the range [0, 2^k - 1] to [0, 1]
> 
> So, to use the RescaleIntensityImageFilter, I would have to have access 
> to the original value for k, which as far as I can tell, only the 
> ImageFileReader has.
> 
> I mostly deal with 8-bit and 16-bit (unsigned) images. If I were to just 
> read them all in as 16-bit images, then I can't figure out how I would 
> then tell which images started out as 8-bit images (and then I would use 
> the RescaleIntensityImageFilter to rescale [0, 255] to [0, 1]) and which 
> images started out as 16-bit images (for which I would transform [0, 
> 65536] to [0, 1]).
> 
> It's easy to find the range of an image, but finding out whether an 
> image with values in the range [5, 230] (say) was originally an 8-bit 
> image, or just a very dim 16-bit image, seems more difficult.
> 
> If this is possible without passing a customConvertPixelTraits class to 
> the ImageFileReader, I would be most happy.
> 
> Thanks,
> 
> Zach
> 
> On Apr 15, 2004, at 9:46 AM, Luis Ibanez wrote:
> 
>>
>> Hi Zach,
>>
>> Is there any particular reason why you don't want
>> to use a RescaleIntensityImageFilter connected to
>> the output of your reader ?
>>
>> This filter will do both the scaling and the type
>> casting for you.
>>
>> Please let us know,
>>
>>
>>   Thanks
>>
>>
>>     Luis
>>
>>
>> ---------------------
>> Zachary Pincus wrote:
>>
>>> Hmm, after looking at DefaultConvertPixelTraits and 
>>> ConvertPixelBuffer, I am not convinced that it is possible to create 
>>> a input-type savvy ConvertPixelTraits.
>>> While the documentation for DefaultConvertPixelTraits states:
>>>
>>>> This implementaion, does a simple assignment operator, so if you are 
>>>> going from from a higher bit representation to a lower bit one (int 
>>>> to char), you may want to specialize and add some sort of transfer 
>>>> function.
>>>
>>> there does not seem to be any way to do this. For example, in the 
>>> ConvertGrayToGray method of ConvertPixelBuffer, this gets called:
>>> OutputConvertTraits
>>>       ::SetNthComponent(0, *outputData++,
>>>                         static_cast<OutputComponentType>
>>>                         (*inputData));
>>> Note the static_cast. So if you wanted to write a ConvertPixelTraits 
>>> class that was savvy about, say, converting ints to chars (as per the 
>>> documentation), you're out of luck because this conversion was 
>>> already done in the static_cast in ConvertPixelBuffer. (I think.)
>>> So it seems that you would really have to write a new version of 
>>> ConvertPixelBuffer that was smart about transforming pixel types 
>>> between each other. OK, this is a bit more of a pain than just 
>>> writing a new ConvertPixelTraits, but whatever. However, even this is 
>>> not possible, because it only seems possible to provide an 
>>> ImageFileReader with a new version of the ConvertPixelTraits, not of 
>>> the ConvertPixelBuffer class.
>>> This seems to be due to the fact that this matter *should* be 
>>> accomplishable through ConvertPixelTraits, but at least to my eye, it 
>>> is not.
>>> Am I missing something fundamental here? Or is it not currently 
>>> possible to add a specialized pixel transfer function to an 
>>> ImageFileReader?
>>> Thanks,
>>> Zach
>>> On Apr 14, 2004, at 4:03 PM, Zachary Pincus wrote:
>>>
>>>> Hello,
>>>>
>>>> My plan is to convert images I read in (initially in heterogeneous 
>>>> pixel types) to floating-point pixels. I intend to rescale each 
>>>> image such that the dynamic range of the image type (e.g. 8 bits, 16 
>>>> bits) is compressed to the floating-point range [0, 1].
>>>>
>>>> That is, I don't mean to "normalize" each image I read in so that 
>>>> [image.min_value, image.max_value] goes to [0, 1], but to convert 
>>>> [ImageType.min_possible_value, ImageType.max_possible_value] to [0, 
>>>> 1]. (If you follow my abused notation!)
>>>>
>>>> Is there any simple way to do this in ITK now? I could write a new 
>>>> version of DefaultConvertPixelTraits for use with the FileReaders, 
>>>> but (a) I don't quite know what all needs to go into this, and (b) 
>>>> if there's an easy way already, I should use that.
>>>>
>>>> Thanks,
>>>> Zach Pincus
>>>>
>>>>
>>>> Department of Biochemistry and Program in Biomedical Informatics
>>>> Stanford University School of Medicine
>>>>
>>>> _______________________________________________
>>>> Insight-users mailing list
>>>> Insight-users at itk.org
>>>> http://www.itk.org/mailman/listinfo/insight-users
>>>>
>>> _______________________________________________
>>> Insight-users mailing list
>>> Insight-users at itk.org
>>> http://www.itk.org/mailman/listinfo/insight-users
>>
>>
>>
>>
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
>