7

我有一个 numpy 数组,它来自 a cv2.imread,所以有dtype = np.uint8and ndim = 3

我想将其转换为 Cythonunsigned int*以与外部 cpp 库一起使用。

我正在尝试cdef unsigned int* buff = <unsigned int*>im.data但是我得到了错误Python objects cannot be cast to pointers of primitive types

我究竟做错了什么?

谢谢

4

2 回答 2

9

更现代的方法是使用内存视图而不是指针:

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

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

  1. 它可以接受任何定义缓冲区接口的类型,例如内置数组模块或 PIL 成像库中的对象。
  2. Memoryviews 可以在不持有 GIL 的情况下传递,这对于并行代码很有用

要从 memoryview 获取指针,请获取第一个元素的地址:

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

这比这样做更好,<np.uint32_t*>mv_buff.data因为它避免了强制转换,并且强制转换通常可以隐藏错误。

于 2019-02-22T17:27:59.650 回答
8

感谢您的意见。通过以下方式解决:

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
于 2012-05-24T10:35:07.777 回答