diff --git a/ants/core/ants_image_io.py b/ants/core/ants_image_io.py index c88c5ac9..70d766f3 100644 --- a/ants/core/ants_image_io.py +++ b/ants/core/ants_image_io.py @@ -99,7 +99,8 @@ def from_numpy( if best_dtype != data.dtype: data = data.astype(best_dtype) - img = _from_numpy(data.T.copy(), origin, spacing, direction, has_components, is_rgb) + # Be explicit about ordering of data - needs to be C-contiguous + img = _from_numpy(data.T.copy(order='C'), origin, spacing, direction, has_components, is_rgb) return img diff --git a/src/itkPyBuffer.hxx b/src/itkPyBuffer.hxx index a1a135c7..df9717a9 100644 --- a/src/itkPyBuffer.hxx +++ b/src/itkPyBuffer.hxx @@ -80,7 +80,6 @@ PyBuffer memset(&pyBuffer, 0, sizeof(Py_buffer)); SizeType size; - SizeType sizeFortran; SizeValueType numberOfPixels = 1; const void * buffer; @@ -114,16 +113,9 @@ PyBuffer { item = PySequence_Fast_GET_ITEM(shapeseq,i); size[i] = (SizeValueType)PyLong_AsLong(item); - sizeFortran[dimension - 1 - i] = (SizeValueType)PyLong_AsLong(item); numberOfPixels *= size[i]; } - bool isFortranContiguous = false; - if( pyBuffer.strides != NULL && pyBuffer.itemsize == pyBuffer.strides[0] ) - { - isFortranContiguous = true; - } - len = numberOfPixels*numberOfComponents*pixelSize; if ( bufferLength != len ) { @@ -139,14 +131,6 @@ PyBuffer RegionType region; region.SetIndex( start ); region.SetSize( size ); - if( isFortranContiguous ) - { - region.SetSize( sizeFortran ); - } - else - { - region.SetSize( size ); - } PointType origin; origin.Fill( 0.0 ); diff --git a/src/readImage.cxx b/src/readImage.cxx index 963ffe58..bdacc2b0 100644 --- a/src/readImage.cxx +++ b/src/readImage.cxx @@ -36,7 +36,13 @@ AntsImage imageRead( std::string filename ) return myImage; } - +/** + * Create an ANTsImage from a numpy array + * + * The data array must be C-contiguous, and ordered correctly + * See "4.1.7 Importing Image Data from a Buffer" + * https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch4.html + */ template AntsImage fromNumpy( nb::ndarray data, nb::tuple datashape ) { diff --git a/tests/test_core_ants_image_io.py b/tests/test_core_ants_image_io.py index 2718e0dc..7af62863 100644 --- a/tests/test_core_ants_image_io.py +++ b/tests/test_core_ants_image_io.py @@ -350,5 +350,27 @@ def test_image_read_write(self): ants.image_read(tmpfile) + def test_image_from_numpy_shape(self): + arr = np.random.randn(1,9,1).astype('float32') + img = ants.from_numpy(arr) + self.assertEqual(img.shape, arr.shape) + nptest.assert_allclose(img.numpy(), arr) + + arr = np.random.randn(2,3,4).astype('float32') + img = ants.from_numpy(arr) + self.assertEqual(img.shape, arr.shape) + nptest.assert_allclose(img.numpy(), arr) + + # Test special case where shape is (1,N), was getting transposed + arr = np.random.randn(1,9).astype('float32') + img = ants.from_numpy(arr) + self.assertEqual(img.shape, arr.shape) + nptest.assert_allclose(img.numpy(), arr) + + arr = np.random.randn(9,1).astype('float32') + img = ants.from_numpy(arr) + self.assertEqual(img.shape, arr.shape) + nptest.assert_allclose(img.numpy(), arr) + if __name__ == '__main__': run_tests()