Skip to content

Commit 71ba10c

Browse files
Copilotthewtex
authored andcommitted
BUG: Fix image_from_array to handle non-contiguous arrays
The issue was that GetImageViewFromArray always reversed the shape for non-vector images, regardless of whether the array was C-contiguous or F-contiguous. However, the C++ code reverses the shape again for F-contiguous arrays, resulting in a double reversal. The fix: Only reverse the shape in Python for C-contiguous arrays. For F-contiguous arrays, pass the shape as-is to C++, which will handle the reversal there. Added comprehensive test cases for both image_from_array and image_view_from_array with transposed arrays. Co-authored-by: thewtex <25432+thewtex@users.noreply.github.com>
1 parent 5b25f72 commit 71ba10c

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

Modules/Bridge/NumPy/wrapping/PyBuffer.i.in

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@
103103
else:
104104
imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[-1:0:-1], ndarr.shape[0])
105105
else:
106-
imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[::-1], 1)
106+
if ndarr.flags['C_CONTIGUOUS']:
107+
imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[::-1], 1)
108+
else:
109+
imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape, 1)
107110

108111
# Keep a reference
109112
imgview._SetBase(ndarr)

Wrapping/Generators/Python/Tests/extras.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,24 @@ def custom_callback(name, progress):
418418
arr_fortran = arr.copy(order="F")
419419
image = itk.GetImageViewFromArray(arr_fortran)
420420
assert np.array_equal(arr_fortran.shape, image.shape)
421+
# Test that image_from_array handles array.T correctly (F-contiguous arrays)
422+
test_arr = np.empty((1, 2, 3))
423+
image_from_arr = itk.image_from_array(test_arr)
424+
image_from_transpose = itk.image_from_array(test_arr.T)
425+
image_from_transpose_copy = itk.image_from_array(test_arr.T.copy())
426+
assert np.array_equal(image_from_arr.shape, test_arr.shape), \
427+
f"Expected shape {test_arr.shape}, got {image_from_arr.shape}"
428+
assert np.array_equal(image_from_transpose.shape, test_arr.T.shape), \
429+
f"Expected shape {test_arr.T.shape}, got {image_from_transpose.shape}"
430+
assert np.array_equal(image_from_transpose_copy.shape, test_arr.T.shape), \
431+
f"Expected shape {test_arr.T.shape}, got {image_from_transpose_copy.shape}"
432+
# Also verify with image_view_from_array for consistency
433+
image_view_from_arr = itk.image_view_from_array(test_arr)
434+
image_view_from_transpose = itk.image_view_from_array(test_arr.T)
435+
assert np.array_equal(image_view_from_arr.shape, test_arr.shape), \
436+
f"Expected shape {test_arr.shape}, got {image_view_from_arr.shape}"
437+
assert np.array_equal(image_view_from_transpose.shape, test_arr.T.shape), \
438+
f"Expected shape {test_arr.T.shape}, got {image_view_from_transpose.shape}"
421439
image = itk.image_from_array(arr, is_vector=True)
422440
assert image.GetImageDimension() == 2
423441
image = itk.GetImageViewFromArray(arr, is_vector=True)

0 commit comments

Comments
 (0)