[英]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.