Project-MONAI / MONAI

AI Toolkit for Healthcare Imaging
https://monai.io/
Apache License 2.0
5.92k stars 1.09k forks source link

ITKReader with inverse indexing does not work #5441

Closed TuanDTr closed 2 years ago

TuanDTr commented 2 years ago

Hi team, I'm using monai.data.LoadImaged with ITKReader and the inverse_indexing option = True to load data. The MONAI version is 1.0.1 and ITK version 5.2.1post1. However, it leads to a segmentation fault error and breaks the dataloader. Downgrading MONAI to 0.9.0 seems to solve the issue but I wonder what the root cause is and how to solve it more efficiently.

Thanks.

wyli commented 2 years ago

thanks for reporting, assuming you are talking about monai.transforms.LoadImaged as there's no monai.data.LoadImaged class in monai. There's no inverse_indexing argument for that class, do you mean reverse_indexing?

if changing the argument doesn't work, could you please follow the bug reporting template to provide more details?

TuanDTr commented 2 years ago

@wyli I'm sorry for the improper bug reporting. Following is the detailed report:

Describe the bug Segmentation fault occurred when loading image with ITKReader and the reverse_indexing option.

To Reproduce

from monai.transforms import AddChanneld, Compose, LoadImaged
from monai.data import ITKReader
# A dict of filepaths of the image and label to load 
input_dict = {"image": "tcia_exp/imagesTr/LUNG1_001.nii.gz", "label": "tcia_exp/labelsTr/LUNG1_001.nii.gz"}
loader = Compose([LoadImaged(keys=("image", "label"), reader=ITKReader(reverse_indexing=True)), AddChanneld(keys=("image", "label"))])
# Output
out = loader(input_dict)
print(out["image"].shape)
print(out["label"].shape)

Expected behavior Shape of the image and label printed image

Environment

Ensuring you use the relevant python executable, please paste the output of:

python -c 'import monai; monai.config.print_debug_info()'
================================
Printing MONAI config...
================================
MONAI version: 1.0.1
Numpy version: 1.23.4
Pytorch version: 1.12.1
MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False
MONAI rev id: 8271a193229fe4437026185e218d5b06f7c8ce69
MONAI __file__: /home/tuan_truong_bayer_com/miniconda3/envs/base_test/lib/python3.9/site-packages/monai/__init__.py

Optional dependencies:
Pytorch Ignite version: NOT INSTALLED or UNKNOWN VERSION.
Nibabel version: 4.0.2
scikit-image version: 0.19.3
Pillow version: 9.2.0
Tensorboard version: NOT INSTALLED or UNKNOWN VERSION.
gdown version: NOT INSTALLED or UNKNOWN VERSION.
TorchVision version: 0.13.1
tqdm version: 4.64.1
lmdb version: NOT INSTALLED or UNKNOWN VERSION.
psutil version: 5.9.3
pandas version: 1.4.4
einops version: NOT INSTALLED or UNKNOWN VERSION.
transformers version: NOT INSTALLED or UNKNOWN VERSION.
mlflow version: NOT INSTALLED or UNKNOWN VERSION.
pynrrd version: NOT INSTALLED or UNKNOWN VERSION.

For details about installing the optional dependencies, please visit:
    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies

================================
Printing system config...
================================
System: Linux
Linux version: Debian GNU/Linux 10 (buster)
Platform: Linux-4.19.0-12-cloud-amd64-x86_64-with-glibc2.28
Processor: 
Machine: x86_64
Python version: 3.9.13
Process name: python
Command: ['python', '-c', 'import monai; monai.config.print_debug_info()']
Open files: [popenfile(path='/home/tuan_truong_bayer_com/.vscode-server/data/logs/20221031T072652/remoteagent.log', fd=19, position=7519, mode='a', flags=33793), popenfile(path='/home/tuan_truong_bayer_com/.vscode-server/data/logs/20221031T072652/ptyhost.log', fd=20, position=6438, mode='a', flags=33793), popenfile(path='/home/tuan_truong_bayer_com/.vscode-server/bin/d045a5eda657f4d7b676dedbfa7aab8207f8a075/vscode-remote-lock.tuan_truong_bayer_com.d045a5eda657f4d7b676dedbfa7aab8207f8a075', fd=99, position=0, mode='w', flags=32769)]
Num physical CPUs: 8
Num logical CPUs: 16
Num usable CPUs: 16
CPU usage (%): [13.8, 6.7, 6.7, 99.5, 7.1, 6.7, 7.6, 100.0, 7.1, 7.1, 8.2, 6.7, 6.6, 7.1, 7.6, 7.1]
CPU freq. (MHz): 2000
Load avg. in last 1, 5, 15 mins (%): [7.7, 8.5, 10.0]
Disk usage (%): 45.5
Avg. sensor temp. (Celsius): UNKNOWN for given OS
Total physical memory (GB): 59.0
Available memory (GB): 47.8
Used memory (GB): 8.3

================================
Printing GPU config...
================================
Num GPUs: 1
Has CUDA: True
CUDA version: 11.6
cuDNN enabled: True
cuDNN version: 8302
Current device: 0
Library compiled for CUDA architectures: ['sm_37', 'sm_50', 'sm_60', 'sm_61', 'sm_70', 'sm_75', 'sm_80', 'sm_86', 'compute_37']
GPU 0 Name: Tesla T4
GPU 0 Is integrated: False
GPU 0 Is multi GPU board: False
GPU 0 Multi processor count: 40
GPU 0 Total memory (GB): 14.8
GPU 0 CUDA capability (maj.min): 7.5
wyli commented 2 years ago

thanks, could you try:

LoadImaged(keys=("image", "label"), reader=ITKReader, reverse_indexing=True)

instead of:

LoadImaged(keys=("image", "label"), reader=ITKReader(reverse_indexing=True))

I think they are different when the loader has multiple workers...

TuanDTr commented 2 years ago

Hi @wyli I think it still does not work for me. The only solution that I found so far is to downgrade MONAI to 0.9.0. But that version is a bit old so I'm looking for some alternative solution. Thanks... image

wyli commented 2 years ago

thanks, I couldn't replicate this issue locally. strange because 0.9.0 vs 1.0.1 the itkreader didn't have any change related to reverse_indexing. if you can share more detailed log or example image volumes I can look into this further

TuanDTr commented 2 years ago

Hi @wyli, I'm sorry for the late reply. I did some further analysis. Actually I was able to print the shape of the tensor but unable to print the tensor itself.

from monai.transforms import AddChanneld, Compose, LoadImaged
from monai.data import ITKReader
# A dict of filepaths of the image and label to load 
input_dict = {"image": "tcia_exp/imagesTr/LUNG1_001.nii.gz", "label": "tcia_exp/labelsTr/LUNG1_001.nii.gz"}
loader = Compose([LoadImaged(keys=("image", "label"), reader=ITKReader(reverse_indexing=True)), AddChanneld(keys=("image", "label"))])
# Output
out = loader(input_dict)
print(out["image"].shape)
print(out["label"].shape)
print(out["image"]) # this gives segmentation fault error
print(out["label"]) # this gives segmentation fault error

In addition, when I print type(out["image"]), MONAI 1.0.1 returns <class 'monai.data.meta_tensor.MetaTensor'> while MONAI 0.9.0 returns <class 'itk.itkPyBufferPython.NDArrayITKBase'>.

ntatsisk commented 2 years ago

Hi @wyli, I am also getting an error when reading images with ITKReader. My data must be quite similar to @beantr96 (Lung CTs from Tcia/Learn2Reg challenge). I am using MONAI==1.0.1 and itk==5.3rc4.post3. Here is a minimal reproducible example:

import os, itk
from monai.apps import download_and_extract
from monai.data import ITKReader
from monai.transforms import LoadImage

# Download and extract Learn2Reg data
root_dir = './'
train_url = "https://zenodo.org/record/3835682/files/training.zip"
folderpath = os.path.join(root_dir, "LungCT")

if not os.path.exists(folderpath):
    os.mkdir(folderpath)

download_and_extract(url=train_url, output_dir=folderpath)

# Read an image with plain itk
filepath = os.path.join(folderpath, "training", "scans", "case_001_exp.nii.gz")
image = itk.imread(filepath, itk.F)
print(image.GetSpacing())

# Read the same image with ITKReader from MONAI (... gives error)
x = LoadImage(reader=ITKReader)(filepath)
print(x.shape)

Output:

training.zip: 266MB [00:05, 50.0MB/s]
2022-11-15 19:46:46,943 - INFO - Downloaded: C:\Users\kntatsis\AppData\Local\Temp\tmprgca21nj\training.zip
2022-11-15 19:46:46,943 - INFO - Expected md5 is None, skip md5 check for file C:\Users\kntatsis\AppData\Local\Temp\tmprgca21nj\training.zip.
2022-11-15 19:46:46,959 - INFO - Non-empty folder exists in LungCT\training, skipped extracting.
itkVectorD3 ([1.75, 1.25, 1.75])
Traceback (most recent call last):
  File "C:\Users\kntatsis\work\monai_itkreader_error\monai_itkreader_error.py", line 22, in <module>
    x = LoadImage(reader=ITKReader)(filepath)
  File "C:\Users\kntatsis\itk-elastix-env\lib\site-packages\monai\transforms\io\array.py", line 271, in __call__
    meta_data = switch_endianness(meta_data, "<")
  File "C:\Users\kntatsis\itk-elastix-env\lib\site-packages\monai\transforms\io\array.py", line 84, in switch_endianness
    data = {k: switch_endianness(v, new) for k, v in data.items()}
  File "C:\Users\kntatsis\itk-elastix-env\lib\site-packages\monai\transforms\io\array.py", line 84, in <dictcomp>
    data = {k: switch_endianness(v, new) for k, v in data.items()}
  File "C:\Users\kntatsis\itk-elastix-env\lib\site-packages\monai\transforms\io\array.py", line 86, in switch_endianness
    raise RuntimeError(f"Unknown type: {type(data).__name__}")
RuntimeError: Unknown type: itkMatrixF44

It does't appear related to reverse_indexing but I hope it is still not off-topic! Thanks :)

wyli commented 2 years ago

thanks for reporting @ntatsisk, that's addressed recently... https://github.com/Project-MONAI/MONAI/pull/5433 the patch will be released in December.

you can uninstall monai 1.0.1 and try pip install monai-weekly or install the current stable release of itk, that's 5.2.1

TuanDTr commented 2 years ago

Hi @wyli, so is there any update from your side regarding the inverse_indexing issue?

wyli commented 2 years ago

Hi @wyli, so is there any update from your side regarding the inverse_indexing issue?

I couldn't replicate the issue using your screenshots.

TuanDTr commented 2 years ago

@wyli That's strange since me and my colleague in the team had the same issue. Have you tried printing the image tensor instead of just the shape. Printing the shape did occasionally work but printing the tensor always led to segmentation fault. Thanks for your help!

wyli commented 2 years ago

I don't have these inputs:

input_dict = {"image": "tcia_exp/imagesTr/LUNG1_001.nii.gz", "label": "tcia_exp/labelsTr/LUNG1_001.nii.gz"}
TuanDTr commented 2 years ago

Hi @wyli I cannot upload those files since they are too large but any Medical Segmentation Decathlon (MSD) images have this issue as well. If you have MSD files perhaps could you try them? Many thanks!

wyli commented 2 years ago

yes I tried, for example Task06_Lung/imagesTr/lung_001.nii.gz and Task06_Lung/labelsTr/lung_001.nii.gz but couldn't reproduce.