Reading images via SCIFIO, handle 5-D images


(Bradley Lowekamp) #1

I am trying to read some light microscopy images. So I compiled SimpleITK with the SCIFIO module:

cmake -DModule_SCIFIO:BOOL=ON -G Ninja ~/src/SimpleITK/Superbuild

Then I did the following:

import SimpleITK as sitk
reader = sitk.ImageFileReader()
reader.SetFileName("my_file.ims")
reader.ReadImageInformation()
print reader

Which displayed:

itk::simple::ImageFileReader
  FileName: "HTA 23 Panel 1 ON Lyve-1 570 CD8 421 CD4 510 Coll IV 700 Foxp3 488 CD31 594 CD3 647 Comp.ims"
  Image Information:
    PixelType: 8-bit unsigned integer
    Dimension: 5
    NumberOfComponents: 1
    Direction: [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]
    Origin: [ 0, 0, 0, 0, 0 ]
    Spacing: [ 0.00037851, 0.000378491, 0.000999928, 1, 1 ]
    Size: [ 4093, 5116, 26, 1, 8 ]
  OutputPixelType: Unknown pixel id
  LoadPrivateTags: 0
  Registered ImageIO:
	BMPImageIO ( *.bmp, *.BMP )
	BioRadImageIO ( *.PIC, *.pic )
	GDCMImageIO
	GE4ImageIO
	GE5ImageIO
	GiplImageIO
	JPEGImageIO ( *.jpg, *.JPG, *.jpeg, *.JPEG )
	MetaImageIO ( *.mha, *.mhd )
	NiftiImageIO ( *.nia, *.nii, *.nii.gz, *.hdr, *.img, *.img.gz )
	NrrdImageIO ( *.nrrd, *.nhdr )
	PNGImageIO ( *.png, *.PNG )
	SCIFIOImageIO
	StimulateImageIO
	TIFFImageIO ( *.tif, *.TIF, *.tiff, *.TIFF )
	VTKImageIO ( *.vtk )
  Debug: 0
  NumberOfThreads: 16
  Commands: (none)
  ProgressMeasurement: 0
  ActiveProcess: (none)

This image is reported as a 5-D one component/channel image with size: [ 4093, 5116, 26, 1, 8 ] SimpleITK does not handle 5-D images so I can’t actually read it. This image to me is a 3-D image with 8 channels. Even ITK proper would have problems reading this image as a VectorImage. The only way to read it in ITK would be to read it into a 5-D scalar image, then use the ExatractImageFilter to get the something like [:,:,:,1,C](python slice notation), the recompose the channels.

How are others dealing with reading multi-channel images from SCIFIO.


(Curtis Rueden) #2

I’d also be interested to hear what others do to work around these limitations. And I’d be happy to discuss improvements to the ITK-SCIFIO code to improve matters. But I won’t have time to hack on code till later this summer, unfortunately.


(Bradley Lowekamp) #3

I have a patch for SimpleITK which I am working on to add support for this.

Basically, it adds an ExtractImageFilter when an image is read to specify how to map the dimensions from the 5D file to the lower dimensional image by specifying starting indexes and sizes. If follows the ExtractImageFilter behavior and any dimension specified with a size of 0, is collapsed, so a 5D image could be reduced by specifying the size of the 4th and 5th dimensions as zero into a 3D image, and the channel can be indexed by specifying the starting index. To create a multi-component image, I then used the ComposeImageFilter to create a Vector Image.

What should make this reasonably efficient is that the Reader->Extractor and pipelined, and the reader “should” perform streaming IO of just the requested region/channel.

Here is a snippet of SimpleITK python code which utilizes the proposed interface. In this case I read the whole file into a 4D image collapsing the 4th dimension, then I converted the 4th dimension of channels into the components of a VectorImage with the ComposeImageFilter

reader = sitk.ImageFileReader()
reader.SetFileName(args.filename)
reader.ReadImageInformation()

img_size = reader.GetSize()

reader.SetExtractSize([0 if v == 1 else v for v in img_size])
img = reader.Execute()

out =  sitk.Compose( [sitk.Extract(img, img.GetSize()[:3]+(0,), [0,0,0, i]) for i in range(img_size[-1])] )

SimpleITK: Channel storage order?