简体   繁体   English

Cython:将2D数组从Python传递到C并检索它

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

I am trying to build a wrapper to a camera driver in written C using Cython. 我正在尝试使用Cython用书面C语言为相机驱动程序构建包装器。 I am new to Cython (started 2 weeks ago). 我是Cython的新手(2周前开始)。 After a lot of struggle, I could successfully develop wrappers for structures, 1D arrays but now I am stuck with 2D arrays. 经过大量的努力,我可以成功开发出用于结构,一维数组的包装器,但现在我被二维数组所困扰。

One of the camera's C APIs takes a 2D array pointer as input and assigns the captured image to it. 相机的C API之一采用2D数组指针作为输入,并将捕获的图像分配给它。 This function needs to be called from Python and the output image needs to be processed/displayed in Python. 需要从Python调用此函数,并且需要在Python中处理/显示输出图像。 After going through the Cython docs and various posts on stack-overflow, I ended up with more confusion. 在浏览了Cython文档和有关堆栈溢出的各种文章之后,我最终感到更加困惑。 I could not figure out how to pass 2D arrays between Python and the C. The driver api looks (somewhat) like this: 我不知道如何在Python和C之间传递2D数组。驱动程序api看起来(有点)像这样:

driver.h 驱动程序

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

c_driver.pyd c_driver.pyd

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

test.pyx 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 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

When compiled, it gives the error: 编译时,会出现错误:

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

In fact, the above code was taken from a stack-overflow post . 实际上,以上代码是从stack-overflow 帖子中获取的 I have tried several other ways but none of them are working. 我尝试了其他几种方法,但是都没有用。 Please let me know how I can get the 2D image into Python. 请让我知道如何将2D图像导入Python。 Thanks in advance. 提前致谢。

You need to type i : 您需要输入i

cdef int i

(Alternatively you can type row_size and it also works) (或者,您可以键入row_size ,它也可以工作)

Once it knows that i is an int then it can work out the type that indexing the tmp_map gives and so the & operator works. 一旦知道i是一个int它就可以计算出tmp_map索引的类型,因此&运算符可以工作。


Normally it's pretty good about figuring out the type of loop variables like i , but I think the issue is that it can't deduce the type of row_size so it decided it can't deduce the type of i since it is deduced from range(row_size) . 通常,搞清楚像i这样的循环变量的类型非常好,但是我认为问题在于它无法推断出row_size的类型,因此它决定不能推断出i的类型,因为它是从range(row_size)推导的range(row_size) Because of that it can't deduce the type of temp_mat[i,0] . 因此,它无法推断temp_mat[i,0]的类型。


I suspect you also you also want to change the return statement to return np.array(temp_mat) - the code you have will likely work most of the time but occasionally np.ascontinuousarray will have to make a copy and mat won't be changed. 我怀疑你也同样想更改return语句以return np.array(temp_mat) -您拥有的代码在大多数情况下可能会工作,但是偶尔np.ascontinuousarray将不得不进行复制并且mat不会被更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM