Python wheels supported image types

I am testing the ITK python package from PyPi (thanks for that :+1::+1:) and I’m trying to read a 2D 16-bit image with the itk.imread function. There is no Unsigned Short (US) type available for that… any alternatives?

Hi @mafuentes, not a python expert, but have you tried to use itk.ImageFileReader? It probably casts the pixels to an available type.

import itk
input_image_path="/path/image.xxx"
reader = itk.ImageFileReader.New(FileName=input_image_path)
reader.Update()
img = reader.GetOutput()

You can check the types that are available by default from python using:

itk.ImageFileReader.GetTypesAsList()
["(<class 'itkImagePython.itkImageCF2'>,)",
 "(<class 'itkImagePython.itkImageCF3'>,)",
 "(<class 'itkImagePython.itkImageCVF22'>,)",
 "(<class 'itkImagePython.itkImageCVF23'>,)",
 "(<class 'itkImagePython.itkImageCVF32'>,)",
 "(<class 'itkImagePython.itkImageCVF33'>,)",
 "(<class 'itkImagePython.itkImageCVF42'>,)",
 "(<class 'itkImagePython.itkImageCVF43'>,)",
 "(<class 'itkImagePython.itkImageF2'>,)",
 "(<class 'itkImagePython.itkImageF3'>,)",
 "(<class 'itkImagePython.itkImageRGBAUC2'>,)",
 "(<class 'itkImagePython.itkImageRGBAUC3'>,)",
 "(<class 'itkImagePython.itkImageRGBUC2'>,)",
 "(<class 'itkImagePython.itkImageRGBUC3'>,)",
 "(<class 'itkImagePython.itkImageSS2'>,)",
 "(<class 'itkImagePython.itkImageSS3'>,)",
 "(<class 'itkImagePython.itkImageUC2'>,)",
 "(<class 'itkImagePython.itkImageUC3'>,)",
 "(<class 'itkImagePython.itkImageVF22'>,)",
 "(<class 'itkImagePython.itkImageVF23'>,)",
 "(<class 'itkImagePython.itkImageVF32'>,)",
 "(<class 'itkImagePython.itkImageVF33'>,)",
 "(<class 'itkImagePython.itkImageVF42'>,)",
 "(<class 'itkImagePython.itkImageVF43'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageF2'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageF3'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageSS2'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageSS3'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageUC2'>,)",
 "(<class 'itkVectorImagePython.itkVectorImageUC3'>,)"]

Maybe UC2 suits your purposes?

1 Like

UC2 type reads the images but down-casts the pixel type which causes loss of information.

I have here a compiled version of ITK with Python wrappers, which is what I have used so far. But the python wheels are much more portable of course and that’s why I’m testing it.

Anyway, thanks for this detail:

:+1:

Hi @mafuentes,

itk.imread() is a convenience function that reads the input image pixel type and tries to read the image using that type of pixels. As @phcerdan mentioned, you can use itk.ImageFileReader that allows you to specify the type of pixel you want to use. So in your case you could try to load you image as a float image if working with float image is not a problem.

ImageType = itk.Image[itk.F, 3] # assuming your image is in 3D
itk.ImageFileReader[ImageType].New(FileName=input_image_path)

You could then cast it (itk.CastImageFilter) or rescale the intensity (itk.RescaleIntensityImageFilter) to convert your image back into an integer type that would work for you.

1 Like

Since Unsigned Short seems to be a fairly common type, we are investigating adding it in the default ITK build. An issue has been opened in the issue tracker.

1 Like

I think that’s a great idea @fbudin. X-Ray CT scanners (as an example) produce 16-bit images for which the Unsigned Short fits the best.

The Float type works for reading 16-bits images as you suggested, thanks :ok_hand:, and the itk.imread() can have as an optional second argument the desired pixel type, so it can do something like this:

itk.imread(fileName=input_image_path, pixelType=itk.F)

2 Likes

A signed 32-bit integer is a superset of the unsigned 16-bit integer. While it would take more memory, would having to promote your pixel type work for your problem?

That idea would be to use larger superset type(s) as a way to avoid having to instantiate everyones specific type.

If you look into the types available for reading images, as posted by @phcerdan in the first reply, there is no 32-bit integer so far. The Float type does the job and it is 32-bit as well.

Pixel type can be promoted, but when you’re reading large 3D images the impact on memory is noticeable because their size doubles, as the space on disc if you write them later as 32-bit.

We typically use a signed short for CT images after the slope and intercept are applied.

FYI, this will be addressed in this patch thanks to @matt.mccormick

The unsigned short pixel type will be supported in the ITK Python packages for the 4.13.0 release.

3 Likes