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
不会更改。
我正在尝试使用 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
不会更改。