您好,我正在使用 python 中的 ctypes 模块从 python 运行一些图像处理 C 代码,目的是优化我的代码并减少执行时间。
为此,我将图像读入 numpy 数组,然后使用内核对图像应用 2D 卷积,生成过滤后的图像。我想在 C 中实现相同的目的,以节省一些执行时间。
因此,问题的第一部分是将 numpy 图像数组转换为 ctype 数组,以便我可以在 C 中执行卷积。 这是我的 C 代码,现在什么都不做,但我只需要它来访问函数定义:
#import <math.h>
void convolution(int *array,int *kernel, int array_height, int array_width,
int kernel_height, int kernel_width) {
int i=0;
这是我的 python 代码,它为这个 C 函数添加了一个包装函数:
_convolution_ = ctypes.cdll.LoadLibrary(working_directory + 'libconvolution.so')
class two_dimensional_matrix_() :
def from_param(self,param) :
typename = type(param).__name__
if hasattr(self,'from_'+typename) :
return getattr(self,'from_'+typename)(param)
else :
raise TypeError('cant convert %s' %typename)
#for a list
def from_list(self,param) :
c_array = ((ctypes.c_int * len(param))*len(param[0]))()
for i in range(len(param)) :
for j in range(len(param[i])) :
c_array[i][j] = ctypes.c_int(param[i][j])
return c_array
#for a tuple
def from_tuple(self,param) :
return self.from_list(param)
#for a numpy array
def from_ndarray(self,param) :
c_array = ((ctypes.c_int * len(param))*len(param[0]))()
for i in range(len(param)) :
for j in range(len(param[i])) :
c_array[i][j] = ctypes.c_int(param[i][j])
return c_array
two_dimensional_matrix = two_dimensional_matrix_()
_convolution_.convolution.argtypes = [
two_dimensional_matrix, two_dimensional_matrix,
ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int
]
_convolution_.convolution.restypes = ctypes.c_void_p
尽管这段代码运行完美,但我想知道的是,是否有更有效的方法来执行从 numpy 数组或列表到 ctypes 数组的转换?因为我在 python 中使用 C 扩展来节省执行时间,所以我希望这个时间尽可能少。
编辑:
根据丹尼尔的建议,我使用了 numpy.ascontiguousarray
,它适用于一维 numpy 数组,这就是我所做的:
c_array = numpy.ascontiguousarray(array,dtype=numpy.uint32)
但是当我对二维数组尝试类似的方法时,它不起作用,这是我尝试过的:
c_array = numpy.ascontiguousarray(array,dtype=numpy.ndarray)
当我使用它时,python 崩溃了。我在这里做错了什么?
最佳答案
最快的方法是,如果没有必要,根本不转换数组。 此代码也适用于列表和元组:
c_array = numpy.ascontiguousarray(param, dtype=int)
pointer = c_array.ctypes.data_as(ctypes.c_void_p)
关于python - 将多维 numpy 数组转换为 ctypes 数组的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33400390/