fepegar / torchio

Medical imaging toolkit for deep learning
https://torchio.org
Apache License 2.0
2.07k stars 241 forks source link

Dataloader fails for some images #669

Closed umgpy closed 2 years ago

umgpy commented 3 years ago

🐛Bug

Data loader fails for some of the subjects, throwing the following error

ITK ERROR: ITK only supports orthonormal direction cosines. No orthonormal definition found!

To reproduce

Tried iterating the images through the data loader

# Your code here
rowid = 43
subid = dat_csv['SubID'][rowid]
img = nib.load(dat_csv['LeftCropPath'][rowid])
img_dat = img.get_fdata()
tio_scalar = tio.ScalarImage(dat_csv['LeftCropPath'][rowid])
print(subid,img_dat.shape)
print(tio_scalar.shape)

>>> N111 (250, 512, 448)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
/tmp/ipykernel_12884/1373327783.py in <module>
      5 tio_scalar = tio.ScalarImage(dat_csv['LeftCropPath'][rowid])
      6 print(subid,img_dat.shape)
----> 7 print(tio_scalar.shape)
...
...

Expected behavior

Should load the image. Loading the image with nibabel has no issues. **Actual behavior**
# Paste the whole error stack trace here
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
/tmp/ipykernel_12884/1373327783.py in <module>
      5 tio_scalar = tio.ScalarImage(dat_csv['LeftCropPath'][rowid])
      6 print(subid,img_dat.shape)
----> 7 print(tio_scalar.shape)

~/user/Pytorch_env_CT/lib/python3.8/site-packages/torchio/data/image.py in shape(self)
    248             shape = tuple(self.data.shape)
    249         else:
--> 250             shape = read_shape(self.path)
    251         return shape
    252 

~/user/Pytorch_env_CT/lib/python3.8/site-packages/torchio/data/io.py in read_shape(path)
     81     reader = sitk.ImageFileReader()
     82     reader.SetFileName(str(path))
---> 83     reader.ReadImageInformation()
     84     num_channels = reader.GetNumberOfComponents()
     85     spatial_shape = reader.GetSize()

~/user/Pytorch_env_CT/lib/python3.8/site-packages/SimpleITK/SimpleITK.py in ReadImageInformation(self)
   8030 
   8031         """
-> 8032         return _SimpleITK.ImageFileReader_ReadImageInformation(self)
   8033 
  8034     def GetPixelID(self):

RuntimeError: Exception thrown in SimpleITK ImageFileReader_ReadImageInformation: /tmp/SimpleITK-build/ITK/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx:1980:
ITK ERROR: ITK only supports orthonormal direction cosines.  No orthonormal definition found!

System info

Output of python <(curl -s https://raw.githubusercontent.com/fepegar/torchio/master/print_system.py):

# Paste here the output of that command in a terminal
Platform:   Linux-4.15.0-47-generic-x86_64-with-glibc2.10
TorchIO:    0.18.56
PyTorch:    1.7.1+cu92
SimpleITK:  2.1.1 (ITK 5.2)
NumPy:      1.21.1
Python:     3.8.8 (default, Apr 13 2021, 19:58:26) 
[GCC 7.3.0]

Possibly related to this

https://github.com/InsightSoftwareConsortium/ITK/issues/2674

Thanks for the help! Cheers

romainVala commented 3 years ago

Hi from the log, I suspect a bad nifti header in your image if you can share the image, I could check ...

umgpy commented 3 years ago

Hi @romainVala , Unfortunately I wouldn't be able to send the image but I could send the nifti header file. Although I am able to load the image without issue witth Nibabel along with on ITKSnap, 3DSlicer and FSLeyes. Let me know if the header alone would do. Thanks!

umgpy commented 3 years ago

Hi @romainVala , Unfortunately I wouldn't be able to send the image but I could send the nifti header file. Although I am able to load the image without issue witth Nibabel along with on ITKSnap, 3DSlicer and FSLeyes. Let me know if the header alone would do. Thanks!

sizeof_hdr 348 data_type INT16 dim0 3 dim1 250 dim2 512 dim3 448 dim4 1 dim5 1 dim6 1 dim7 1 vox_units mm time_units s datatype 4 nbyper 2 bitpix 16 pixdim0 -1.000000 pixdim1 0.685547 pixdim2 0.685547 pixdim3 0.625000 pixdim4 1.000000 pixdim5 1.000000 pixdim6 1.000000 pixdim7 1.000000 vox_offset 352 cal_max 0.000000 cal_min 0.000000 scl_slope 0.078126 scl_inter -463.960938 phase_dim 0 freq_dim 0 slice_dim 0 slice_name Unknown slice_code 0 slice_start 0 slice_end 0 slice_duration 0.000000 toffset 0.000000 intent Unknown intent_code 0 intent_name intent_p1 0.000000 intent_p2 0.000000 intent_p3 0.000000 qform_name Unknown qform_code 0 qto_xyz:1 -0.685547 0.000000 -0.000000 -3.813309 qto_xyz:2 0.000000 0.685547 -0.000000 -174.814514 qto_xyz:3 0.000000 0.000000 0.625000 -292.000000 qto_xyz:4 0.000000 0.000000 0.000000 1.000000 qform_xorient Right-to-Left qform_yorient Posterior-to-Anterior qform_zorient Inferior-to-Superior sform_name Unknown sform_code 2 sto_xyz:1 -0.685547 0.000000 0.000000 -3.813309 sto_xyz:2 0.000000 0.685547 0.000000 -174.814514 sto_xyz:3 0.000000 0.000000 0.625000 -292.000000 sto_xyz:4 0.000000 0.000000 0.000000 1.000000 sform_xorient Right-to-Left sform_yorient Posterior-to-Anterior sform_zorient Inferior-to-Superior file_type NIFTI-1+ file_code 1 descrip Time=105757.678 aux_file

romainVala commented 3 years ago

That is strange, your header looks fine. I do not understand why you get an error

To be sure, can you try

import SimpleITK as sitk

path='/path/to/image.nii'   
reader = sitk.ImageFileReader()
reader.SetFileName(str(path))
reader.ReadImageInformation()

if you get the same error, this mean the image has something wrong, if you do not get any error this mean dat_csv['LeftCropPath'][rowid] gives the wrong path

fepegar commented 2 years ago

This seems to be related to ITK, which doesn't seem to be able to read images with non-orthogonal axes, such as some CT scans. I suggest you raise this issue in the ITK GitHub repository.

naga-karthik commented 2 years ago

I had the exact same ITK Error, causing it to fail to load some images (whereas nibabel was able to load all the images). In my case, I was on torchIO version 0.18.84 and simpleITK version 2.1.1.2.

I was able to fix it by downgrading SimpleITK to version 2.0.2 specifically.