将numpy数组转换为cython指针

9
我有一个numpy数组,它来自于 cv2.imread ,因此具有 dtype = np.uint8 ndim = 3
我想将它转换为Cython的 unsigned int * ,以便与外部C ++库一起使用。
我尝试过 cdef unsigned int * buff = <unsigned int * > im.data ,但是我收到了错误消息 Python对象不能被转换为基本类型指针 我做错了什么?
谢谢

这个问题的答案可能会有所帮助:https://dev59.com/wnA75IYBdhLWcg3w49YR - Janne Karila
2
请注意,np.uint8unsigned char 而不是 unsigned int - Janne Karila
2个回答

12

更现代的方法是使用memoryview而不是指针:

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

[:,;,::1]语法告诉Cython该内存视图是三维的并且在内存中具有C连续性。将类型定义为内存视图而不是numpy数组的优点是:

  1. 它可以接受定义了缓冲区接口的任何类型,例如内置的array模块或来自PIL图像库的对象。
  2. 内存视图可以在没有保持GIL的情况下传递,这对于并行代码非常有用

要从内存视图中获取指针,请获取第一个元素的地址:

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

这比使用<np.uint32_t*>mv_buff.data更好,因为它避免了强制转换,而且强制转换经常会隐藏错误。


9
感谢您的评论。解决方法如下:
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

1
你应该使用np.uint而不是np.uint32(在某些系统上,unsigned int可能是64位)。 - jfs
2
根据 https://github.com/cython/cython/wiki/tutorials-NumpyPointerToC,&np_buff[0,0,0] 比 <unsigned int*> np_buff.data 更好。 - Syrtis Major

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接