Cython:将二维数组从 Python 传递到 C 并检索它

Cython: Pass a 2D array from Python to a C and retrieve it

我正在尝试使用 Cython 以书面 C 语言为相机驱动程序构建一个包装器。我是 Cython 的新手(2 周前开始)。经过大量的努力,我可以成功地为结构、一维数组开发包装器,但现在我被二维数组困住了。

相机的一个 C API 将二维数组指针作为输入并将捕获的图像分配给它。此函数需要从 Python 调用,输出图像需要在 Python 中 processed/displayed。在浏览了 Cython 文档和关于 stack-overflow 的各种帖子后,我感到更加困惑。我不知道如何在 Python 和 C 之间传递二维数组。驱动程序 api 看起来(有点)像这样:

driver.h

void assign_values2D(double **matrix, unsigned int row_size, unsigned int column_size);

c_driver.pyd

cdef extern from "driver.h":
    void assign_values2D(double **matrix, unsigned int row_size, unsigned int column_size)

test.pyx

from c_driver import assign_values2D
import numpy as np
cimport numpy as np
cimport cython
from libc.stdlib cimport malloc, free
import ctypes

@cython.boundscheck(False)
@cython.wraparound(False)
def assignValues2D(self, np.ndarray[np.double_t,ndim=2,mode='c']mat):
    row_size,column_size = np.shape(mat)
    cdef np.ndarray[double, ndim=2, mode="c"] temp_mat = np.ascontiguousarray(mat, dtype = ctypes.c_double)
    cdef double ** mat_pointer = <double **>malloc(column_size * sizeof(double*))
    if not mat_pointer:
        raise MemoryError
    try:
        for i in range(row_size):
            mat_pointer[i] = &temp_mat[i, 0]

        assign_values2D(<double **> &mat_pointer[0], row_size, column_size)
        return np.array(mat)
    finally:
        free(mat_pointer)

test_camera.py

b = np.zeros((5,5), dtype=np.float) # sample code
print "B Before = "
print b
assignValues2D(b)
print "B After = "
print b

编译时报错:

Error compiling Cython file:
------------------------------------------------------------
...
    if not mat_pointer:
        raise MemoryError
    try:
        for i in range(row_size):
            mat_pointer[i] = &temp_mat[i, 0]
                ^
 ------------------------------------------------------------
 test.pyx:120:21: Cannot take address of Python variable

事实上,上面的代码是从堆栈溢出中提取的post。我尝试了其他几种方法,但其中 none 有效。请告诉我如何将 2D 图像放入 Python。提前致谢。

您需要输入 i:

cdef int i

(或者您可以输入 row_size 也可以)

一旦它知道 i 是一个 int 然后它就可以计算出索引 tmp_map 给出的类型,因此 & 运算符起作用。


通常情况下,弄清楚 i 之类的循环变量的类型非常好,但我认为问题在于它无法推断出 row_size 的类型,所以它决定它不能' t 推导出 i 的类型,因为它是从 range(row_size) 推导出来的。因此,它无法推断出 temp_mat[i,0].

的类型

我怀疑你也想将 return 语句更改为 return np.array(temp_mat) - 你的代码可能大部分时间都可以工作,但偶尔 np.ascontinuousarray 必须一份,mat 不会更改。