I have the following Cython function
def detect(width, height, np.ndarray[np.uint8_t, ndim=1] frame):
cdef detection_payload* detection = scan_frame(width, height, frame)
return DetectionPayload()._setup(detection)
This is the signature of scan_frame
cdef extern from "tag36h11_detector/tag36h11_detector.h":
cdef struct detection_payload:
int size
apriltag_detection_t* detections
ctypedef detection_payload detection_payload_t
detection_payload* scan_frame(int width, int height, uint8_t* data)
This is how I'm trying to pass an array into detect
// test.py
from tag36h11_detector import detect
import numpy as np
a = np.array([1,2,3], dtype=np.uint8)
detect(4, 5, a)
This is the error I get...
Traceback (most recent call last): File "test.py", line 6, in detect(4, 5, a) File "tag36h11_detector.pyx", line 67, in tag36h11_detector.detect cdef detection_payload* detection = scan_frame(width, height, frame) TypeError: expected bytes, numpy.ndarray found
While the internal data of your NumPy array is of type uint8_t
, the array itself is not a pointer, so it does not match the type uint8_t*
. You will need to make a pointer to the NumPy array along the lines of &frame[0]
(the [0]
indicates the 0th element of the array and the &
creates a pointer to it) depending on the internal data structure of the array. Also make sure that the array is C-contiguous by using numpy.asarray or the like.
Example
cdef detection_payload* detection = scan_frame(width, height, &frame[0])
It is possible to use the method proposed by Capow, but I would advocate to replace the numpy arrays by memoryviews in the cython code, that has the following advantages:
That means:
def detect(width, height, unsigned int[::1] frame not None):
cdef detection_payload* detection = scan_frame(width, height, &frame[0])
...
We still use &frame[0]
to get the pointer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.