Wednesday 15 June 2011

python - Transposing a numpy matrix causes cv's draw functions to throw errors -



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

No comments:

Post a Comment