From c613ee2da43bc43425acd81ee08fa4f18fa30e7f Mon Sep 17 00:00:00 2001 From: Jaime Fernandez Date: Thu, 11 Jun 2015 09:41:12 -0700 Subject: [PATCH] BUG: ndarray to Mat conversion with NPY_RELAXED_STRIDES set Add logic to avoid nonsense strides when dimension size is 1 and NumPy is built with NPY_RELAXED_STRIDES from tripping OpenCV. --- modules/python/src2/cv2.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 974545994b..fbe4c7f01e 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -315,8 +315,9 @@ static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo info) // a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases // b) transposed arrays, where _strides[] elements go in non-descending order // c) flipped arrays, where some of _strides[] elements are negative - if( (i == ndims-1 && (size_t)_strides[i] != elemsize) || - (i < ndims-1 && _strides[i] < _strides[i+1]) ) + // the _sizes[i] > 1 is needed to avoid spurious copies when NPY_RELAXED_STRIDES is set + if( (i == ndims-1 && _sizes[i] > 1 && (size_t)_strides[i] != elemsize) || + (i < ndims-1 && _sizes[i] > 1 && _strides[i] < _strides[i+1]) ) needcopy = true; } @@ -343,10 +344,21 @@ static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo info) _strides = PyArray_STRIDES(oarr); } - for(int i = 0; i < ndims; i++) + // Normalize strides in case NPY_RELAXED_STRIDES is set + size_t default_step = elemsize; + for ( int i = ndims - 1; i >= 0; --i ) { size[i] = (int)_sizes[i]; - step[i] = (size_t)_strides[i]; + if ( size[i] > 1 ) + { + step[i] = (size_t)_strides[i]; + default_step = step[i] * size[i]; + } + else + { + step[i] = default_step; + default_step *= size[i]; + } } // handle degenerate case