将1D numpy数组传递给Cython函数

时间:2017-10-01 21:00:22

标签: python numpy cython

我有以下Cython功能

PROC SQL NOPRINT;
create table want as
select PatientID,
       count(distinct Diagnosis) as count
   from have
   where Diagnosis in (282.1, 232.1, 250.02)
   group by PatientID;
quit;

这是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)

的签名
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)

的方法
detect

这是我得到的错误......

  

追踪(最近一次通话):     文件“test.py”,第6行,in       检测(4,5,a)     文件“tag36h11_detector.pyx”,第67行,在tag36h11_detector.detect中       cdef detection_payload * detection = scan_frame(宽度,高度,帧)   TypeError:期望字节,找到numpy.ndarray

2 个答案:

答案 0 :(得分:1)

虽然NumPy数组的内部数据是uint8_t类型,但数组本身不是指针,因此它与类型uint8_t*不匹配。您将需要沿&frame[0]行创建一个指向NumPy数组的指针([0]表示数组的第0个元素,&创建指向它的指针),具体取决于数组的内部数据结构。还可以使用numpy.asarray等确保数组是C-contiguous。

实施例

cdef detection_payload* detection = scan_frame(width, height, &frame[0])

答案 1 :(得分:0)

可以使用Capow提出的方法,但我主张用cython代码中的memoryviews替换numpy数组,具有以下优点:

  1. 该函数可以在没有numpy的情况下使用,也可以与支持内存视图的其他类一起使用
  2. 你可以确保记忆是连续的
  3. 你的cython模块根本不依赖于numpy
  4. 这意味着:

    def detect(width, height, unsigned int[::1] frame not None):
        cdef detection_payload* detection = scan_frame(width, height, &frame[0])
        ...
    

    我们仍然使用&frame[0]来获取指针。