@@ -60,6 +60,7 @@ Mat ndarray_to_mat(ndarray_obj_t *ndarray)
60
60
// We have an ndarray_obj_t, so these checks have already been done.
61
61
62
62
// https://github.com/opencv/opencv/blob/aee828ac6ed3e45d7ca359d125349a570ca4e098/modules/python/src2/cv2_convert.cpp#L130-L172
63
+ bool needcopy = false ;
63
64
int type = ndarray_type_to_mat_depth (ndarray->dtype );
64
65
65
66
int ndims = ndarray->ndim ;
@@ -71,17 +72,41 @@ Mat ndarray_to_mat(ndarray_obj_t *ndarray)
71
72
_strides[i] = ndarray->strides [ULAB_MAX_DIMS - ndarray->ndim + i];
72
73
}
73
74
74
- // https://github.com/opencv/opencv/blob/aee828ac6ed3e45d7ca359d125349a570ca4e098/modules/python/src2/cv2_convert.cpp#L176-L221
75
+ // https://github.com/opencv/opencv/blob/aee828ac6ed3e45d7ca359d125349a570ca4e098/modules/python/src2/cv2_convert.cpp#L176-L241
75
76
bool ismultichannel = ndims == 3 ;
76
77
78
+ for ( int i = ndims-1 ; i >= 0 && !needcopy; i-- )
79
+ {
80
+ // these checks handle cases of
81
+ // a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases
82
+ // b) transposed arrays, where _strides[] elements go in non-descending order
83
+ // c) flipped arrays, where some of _strides[] elements are negative
84
+ // the _sizes[i] > 1 is needed to avoid spurious copies when NPY_RELAXED_STRIDES is set
85
+ if ( (i == ndims-1 && _sizes[i] > 1 && (size_t )_strides[i] != elemsize) ||
86
+ (i < ndims-1 && _sizes[i] > 1 && _strides[i] < _strides[i+1 ]) )
87
+ needcopy = true ;
88
+ }
89
+
77
90
if (ismultichannel)
78
91
{
79
92
int channels = ndims >= 1 ? (int )_sizes[ndims - 1 ] : 1 ;
80
93
ndims--;
81
94
type |= CV_MAKETYPE (0 , channels);
95
+
96
+ if (ndims >= 1 && _strides[ndims - 1 ] != (size_t )elemsize*_sizes[ndims])
97
+ needcopy = true ;
98
+
82
99
elemsize = CV_ELEM_SIZE (type);
83
100
}
84
101
102
+ if (needcopy)
103
+ {
104
+ ndarray = ndarray_from_mp_obj (ndarray_copy (ndarray), 0 );
105
+ for (int i = 0 ; i < ndarray->ndim ; i++) {
106
+ _strides[i] = ndarray->strides [ULAB_MAX_DIMS - ndarray->ndim + i];
107
+ }
108
+ }
109
+
85
110
// https://github.com/opencv/opencv/blob/aee828ac6ed3e45d7ca359d125349a570ca4e098/modules/python/src2/cv2_convert.cpp#L243-L261
86
111
int size[CV_MAX_DIM+1 ] = {};
87
112
size_t step[CV_MAX_DIM+1 ] = {};
0 commit comments