python - Transposing a numpy matrix causes cv's draw functions to throw errors -
i've been running few problems using cv display images numpy matrices when transpose them.
consider next code.
import cv2, numpy np ... ones = np.ones((100,100)) onest = np.copy(ones.t) onesct = np.copy(ones.t, order='c') cv2.circle(ones, (50,50), 3, (0), thickness=-1) cv2.circle(onesct, (50,50), 3, (0), thickness=-1) cv2.circle(onest, (50,50), 3, (0), thickness=-1)
the first 2 "cv2.circle" calls work 3rd 1 gives me next error:
102 cv2.circle(ones, (50,50), 3, (0), thickness=-1) 103 cv2.circle(onesct, (50,50), 3, (0), thickness=-1) --> 104 cv2.circle(onest, (50,50), 3, (0), thickness=-1) typeerror: layout of output array img incompatible cv::mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
why happen transposed matrices not if alter order in memory copied? me, matrices same.
at 1 level of abstraction, matrices same. @ lower level, 2 of them have info stored using c convention (row-major order) arrays, , other (onest
) uses fortran convention (column-major order). apparently cv2.circle
expects c-contiguous array.
you can check order using flags
attribute. note f_contiguous
flag of onest
true:
in [24]: ones.flags out[24]: c_contiguous : true f_contiguous : false owndata : true writeable : true aligned : true updateifcopy : false in [25]: onest.flags out[25]: c_contiguous : false f_contiguous : true owndata : true writeable : true aligned : true updateifcopy : false in [26]: onesct.flags out[26]: c_contiguous : true f_contiguous : false owndata : true writeable : true aligned : true updateifcopy : false
a concise way check order info np.isfortran
:
in [27]: np.isfortran(onest) out[27]: true
onest
uses fortran order because transpose of 2-d array implemented in numpy swapping "strides" each dimension, without copying array of values in memory.
for example,
in [28]: x = np.array([[1, 2, 3], [4, 5, 6]]) in [29]: np.isfortran(x) out[29]: false in [30]: np.isfortran(x.t) out[30]: true
(this makes transpose operation efficient.)
you copied transposed array create onest
, if @ docstring of np.copy
, you'll see default value of order
argument 'k'
, means "match layout of closely possible." in particular, preserves fortran order in case. onesct
, on other hand, c-contiguous array because explicitly told np.copy
order re-create using c convention.
python opencv numpy