-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Describe the bug
The convert_to_channel_last method of the ImageWriter class implicitly converts data from a MetaTensor to an ndarray here:
data = np.squeeze(data, -1)
This causes downstream issues elsewhere. For example, the documentation for ITKWriter states that by setting affine_lps_to_ras to None, the flag will be determined automatically using the meta["space"] attribute:
affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``.
Set to ``True`` to be consistent with ``NibabelWriter``,
otherwise the affine matrix is assumed already in the ITK convention.
Set to ``None`` to use ``data_array.meta[MetaKeys.SPACE]`` to determine the flag.
And the create_backend_obj method does attempt to do this:
if isinstance(data_array, MetaTensor) and affine_lps_to_ras is None:
affine_lps_to_ras = (
data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS
) # do the converting from LPS to RAS only if the space type is currently LPS.
However, the check isinstance(data_array, MetaTensor) is always false due to convert_to_channel_last being called earlier (assuming squeeze_end_dims = True, which is the default, and that there are channels to squeeze).
To Reproduce
import numpy as np
import monai as mn
arr = np.random.rand(1, 2, 3, 4, 5)
meta = mn.data.MetaTensor(arr)
writer = mn.data.ITKWriter()
writer.set_data_array(meta)
print(type(writer.data_obj)) # <class 'numpy.ndarray'>Expected behavior
Type should be <class 'monai.data.meta_tensor.MetaTensor'>
Note that the expected behavior can be achieved by making the following change here:
Old:
data = np.squeeze(data, -1)
New:
data = data.squeeze(-1)
Screenshots
N/A
Environment
python -c "import monai; monai.config.print_debug_info()"
================================
Printing MONAI config...
================================
MONAI version: 1.6.dev2544
Numpy version: 2.3.2
Pytorch version: 2.5.1+cu124
MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False
MONAI rev id: f910be902091ce9efdc2928e1eb473fd607bfeb9
MONAI __file__: /home/<username>/Developer/dv-cardio-seg/.venv/lib/python3.12/site-packages/monai/__init__.py
Optional dependencies:
Pytorch Ignite version: NOT INSTALLED or UNKNOWN VERSION.
ITK version: 5.4.4
Nibabel version: 5.3.2
scikit-image version: NOT INSTALLED or UNKNOWN VERSION.
scipy version: NOT INSTALLED or UNKNOWN VERSION.
Pillow version: 11.0.0
Tensorboard version: NOT INSTALLED or UNKNOWN VERSION.
gdown version: NOT INSTALLED or UNKNOWN VERSION.
TorchVision version: NOT INSTALLED or UNKNOWN VERSION.
tqdm version: 4.66.6
lmdb version: NOT INSTALLED or UNKNOWN VERSION.
psutil version: NOT INSTALLED or UNKNOWN VERSION.
pandas version: 2.2.3
einops version: 0.8.1
transformers version: NOT INSTALLED or UNKNOWN VERSION.
mlflow version: NOT INSTALLED or UNKNOWN VERSION.
pynrrd version: NOT INSTALLED or UNKNOWN VERSION.
clearml 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...
================================
`psutil` required for `print_system_info`
================================
Printing GPU config...
================================
Num GPUs: 1
Has CUDA: True
CUDA version: 12.4
cuDNN enabled: True
NVIDIA_TF32_OVERRIDE: None
TORCH_ALLOW_TF32_CUBLAS_OVERRIDE: None
cuDNN version: 90100
Current device: 0
Library compiled for CUDA architectures: ['sm_50', 'sm_60', 'sm_70', 'sm_75', 'sm_80', 'sm_86', 'sm_90']
GPU 0 Name: NVIDIA GeForce RTX 4090
GPU 0 Is integrated: False
GPU 0 Is multi GPU board: False
GPU 0 Multi processor count: 128
GPU 0 Total memory (GB): 23.6
GPU 0 CUDA capability (maj.min): 8.9
Additional context
N/A