преобразовать массив numpy в указатель cython

У меня есть массив numpy, полученный из cv2.imread, а также dtype = np.uint8 и ndim = 3.

Я хочу преобразовать его в Cython unsigned int* для использования с внешней библиотекой cpp.

Я пытаюсь cdef unsigned int* buff = <unsigned int*>im.data, но получаю ошибку Python objects cannot be cast to pointers of primitive types

Что я делаю неправильно?

Спасибо


person Ferguzz    schedule 23.05.2012    source источник
comment
Ответы на этот вопрос, вероятно, помогут: stackoverflow.com/q/3046305/222914   -  person Janne Karila    schedule 23.05.2012
comment
Обратите также внимание, что np.uint8 это unsigned char, а не unsigned int.   -  person Janne Karila    schedule 23.05.2012


Ответы (2)


Спасибо за ваши комментарии. решается:

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
person Ferguzz    schedule 24.05.2012
comment
вам, вероятно, следует использовать np.uint вместо np.uint32 (unsigned int может быть 64-битным в некоторых системах). - person jfs; 24.05.2012
comment
согласно github.com/cython/cython/wiki/tutorials-NumpyPointerToC, &np_buff[0,0,0] будет лучше, чем ‹unsigned int*› np_buff.data - person Syrtis Major; 02.07.2014

Более современным способом было бы использование памяти, а не указателя:

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

Синтаксис [:,;,::1] говорит Cython, что представление памяти является трехмерным, а C непрерывным в памяти. Преимущество определения типа как представления памяти, а не массива numpy,

  1. он может принимать любой тип, определяющий интерфейс буфера, например, встроенный модуль массива или объекты из библиотеки изображений PIL.
  2. Представления памяти можно передавать без удержания GIL, что полезно для параллельного кода.

Чтобы получить указатель из memoryview, получите адрес первого элемента:

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

Это лучше, чем <np.uint32_t*>mv_buff.data, потому что позволяет избежать приведения типов, а приведения часто могут скрывать ошибки.

person DavidW    schedule 22.02.2019