Skip to content

Commit ca56140

Browse files
authored
Merge branch 'dev' into fix/affine-transform-align-corners
2 parents 690959f + 862f3a6 commit ca56140

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

monai/data/image_reader.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,8 @@ def get_data(self, img) -> tuple[np.ndarray, dict]:
11021102
This function returns two objects, first is numpy array of image data, second is dict of metadata.
11031103
It constructs `affine`, `original_affine`, and `spatial_shape` and stores them in meta dict.
11041104
When loading a list of files, they are stacked together at a new dimension as the first dimension,
1105-
and the metadata of the first image is used to present the output metadata.
1105+
and the metadata of the first image is used to present the output metadata. The returned arrays
1106+
preserve the ordering in the original data, typically this is F-ordering for NIfTI files.
11061107
11071108
Args:
11081109
img: a Nibabel image object loaded from an image file or a list of Nibabel image objects.
@@ -1217,7 +1218,7 @@ def _get_array_data(self, img, filename):
12171218
data_offset = img.dataobj.offset
12181219
data_dtype = img.dataobj.dtype
12191220
return image[data_offset:].view(data_dtype).reshape(data_shape, order="F")
1220-
return np.asanyarray(img.dataobj, order="C")
1221+
return np.asanyarray(img.dataobj)
12211222

12221223

12231224
class NumpyReader(ImageReader):

tests/data/test_init_reader.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111

1212
from __future__ import annotations
1313

14+
import os
15+
import tempfile
1416
import unittest
1517

18+
import numpy as np
19+
1620
from monai.data import ITKReader, NibabelReader, NrrdReader, NumpyReader, PILReader, PydicomReader
1721
from monai.transforms import LoadImage, LoadImaged
1822
from tests.test_utils import SkipIfNoModule
@@ -76,6 +80,26 @@ def test_readers_to_gpu(self):
7680
inst = NibabelReader(to_gpu=to_gpu)
7781
self.assertIsInstance(inst, NibabelReader)
7882

83+
@SkipIfNoModule("nibabel")
84+
def test_nibabel_reader_avoids_eager_c_order_copy(self):
85+
import nibabel as nib
86+
87+
test_image = np.arange(2 * 3 * 4, dtype=np.int16).reshape(2, 3, 4)
88+
with tempfile.TemporaryDirectory() as tempdir:
89+
for suffix in (".nii", ".nii.gz"):
90+
with self.subTest(suffix=suffix):
91+
filename = os.path.join(tempdir, f"test_image{suffix}")
92+
nib.save(nib.Nifti1Image(test_image, np.eye(4)), filename)
93+
94+
reader = NibabelReader(mmap=False)
95+
img = reader.read(filename)
96+
data, _ = reader.get_data(img)
97+
98+
np.testing.assert_array_equal(data, test_image)
99+
# The reader must not force an eager C-order copy; the native
100+
# (F-order) layout from nibabel should be preserved here.
101+
self.assertFalse(data.flags.c_contiguous)
102+
79103

80104
if __name__ == "__main__":
81105
unittest.main()

0 commit comments

Comments
 (0)