Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert numpy array to cython pointer

I have a numpy array which came from a cv2.imread and so has dtype = np.uint8 and ndim = 3.

I want to convert it to a Cython unsigned int* for use with an external cpp library.

I am trying cdef unsigned int* buff = <unsigned int*>im.data however I get the error Python objects cannot be cast to pointers of primitive types

What am I doing wrong?

Thanks

like image 389
Ferguzz Avatar asked May 23 '12 11:05

Ferguzz


2 Answers

The more modern way would be to use a memoryview rather than a pointer:

cdef np.uint32_t[:,:,::1] mv_buff = np.ascontiguousarray(im, dtype = np.uint32)

The [:,;,::1] syntax tells Cython the memoryview is 3D and C contiguous in memory. The advantage of defining the type to be a memoryview rather than a numpy array is

  1. it can accept any type that defines the buffer interface, for example the built in array module, or objects from the PIL imaging library.
  2. Memoryviews can be passed without holding the GIL, which is useful for parallel code

To get the pointer from the memoryview get the address of the first element:

cdef np.uint32_t* im_buff = &mv_buff[0,0,0]

This is better than doing <np.uint32_t*>mv_buff.data because it avoids a cast, and casts can often hide errors.

like image 133
DavidW Avatar answered Nov 08 '22 20:11

DavidW


thanks for your comments. solved by:

cdef np.ndarray[np.uint32_t, ndim=3, mode = 'c'] np_buff = np.ascontiguousarray(im, dtype = np.uint32)
cdef unsigned int* im_buff = <unsigned int*> np_buff.data
like image 30
Ferguzz Avatar answered Nov 08 '22 21:11

Ferguzz