Differences between using component ITKImageIO and explicitly setting ITKIOTIFF

,

I have found an odd behavior, but only tested in my local computer.

If I use any automatic IO detection (pre 4.13 approach, or newer/cleaner ITKImageIO) and try to read a 3D .tiff image, for example, 64x64x16, I get a 64x64x1 image from the reader.
However if I explicitly use ITKIOTIFF, it works as expected.

Here is the minimal working example to test/reproduce it: https://github.com/phcerdan/bug_itkimageio.
test it using ctest -V and see differences changing the cmake option USE_ITKIMAGEIO:

if (USE_ITKIMAGEIO) # All available IO
    set(use_itk_modules
        ITKImageIO
        )
else (USE_ITKIMAGEIO) # Only a few IO
    set(use_itk_modules
        ITKIOImageBase
        ITKIOTIFF
        )
endif (USE_ITKIMAGEIO)
find_package(ITK COMPONENTS ${use_itk_modules} REQUIRED)
include(${ITK_USE_FILE})

Maybe another ImageIO, that can also read a TIFF file, reads the file before itk::TIFFImageIO gets a chance.

After calling ->Update() on the reader, what does printing reader->GetImageIO() return?

Good point, that’s exactly what happening, it is SCIFIOImageIO.

  reader->GetImageIO()->Print( std::cout );

I get:

SCIFIOImageIO (0x55fb3dd814e0)
  RTTI typeinfo:   itk::SCIFIOImageIO
  Reference Count: 1
  Modified Time: 228
  Debug: Off
  Object Name:
  Observers:
    none
  AbortGenerateData: Off
  Progress: 0
  FileName: /path/to/itk_bug_io/src/collagen_64x64x16.tiff
  FileType: Binary
  ByteOrder: BigEndian
  IORegion:
    ImageIORegion (0x55fb3dd81578)
      Dimension: 3
      Index: 0 0 0
      Size: 64 64 1
  Number of Components/Pixel: 1
  Pixel Type: scalar
  Component Type: unsigned_short
  Dimensions: ( 64 64 1 16 )
  Origin: ( 0 0 0 0 )
  UseCompression: Off
  UseStreamedReading: On
  UseStreamedWriting: Off
  ExpandRGBPalette: On
  IsReadAsScalarPlusPalette: False


ImageSize:[64, 64, 1]
Expected:[64, 64, 16]
Error, different sizes [64, 64, 1]!= expected: [64, 64, 16]

Is there a way to give preference to ITKIOTIFF?

One option is to call SetImageIO on the reader. But, it means other IO formats will not be supported.

You could also try calling itk::TIFFImageIOFactory::RegisterOneFactory() at the start of the program. This may put TIFF higher in the factory list, but that assumption needs to be tested. We do not yet have a good way to explicitly specify the factory preferences.

In the end, it may be best create a itk::TIFFImageIO, call CanReadFile() on it, then set it as the ImageIO for the itk::ImageFileReader if it can read the file.

Other option is to fix the SCIFIO reader :wink: .

2 Likes

Thanks @matt.mccormick, I would go for your last suggestion.
Fixing it will be way better of course, but maybe it’s not even a bug but a failure in converting the image from the microscopy format to tiff.

The bioformat reader is reading the image as a 4D:
In itk: Dimensions: ( 64 64 1 16 ).
In OME Metadata (from imageJ bioformats plugins):

<Pixels BigEndian="true" DimensionOrder="XYCZT" ID="Pixels:0" Interleaved="false" SignificantBits="16"
SizeC="1" SizeT="16" SizeX="64" SizeY="64" SizeZ="1" TimeIncrement="1.0" TimeIncrementUnit="s" Type="uint16">

So maybe it is just a metadata conversion error…

2 Likes

@ctrueden Any thoughts on whether we are handling the dimensions correctly?

This is tangentially related. The ImageFileReader by default just produced the first “slice” of a higher dimension volume. Part of this behavior is dictated by this section of code in the ImageFilterReader:

I believe an important motivation for this behavior is that a DICOM slice is reported as (X,Y,1), and this behavior enables it to be loaded into a 2D image.

There is no automatic middle dimension squishing for ITK.

I recently enabled SCIFIO for SimpleITK and the if I recall correctly a basic 2D image was reported as (X,Y,1,1) for it’s size and refused to load. I should try it with the new 4D feature in SimpleITK though.

1 Like