首页 文章

将多维numpy数组转换为ctypes数组的最有效方法

提问于
浏览
0

您好,我在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扩展来节省执行时间,所以我希望这个时间尽可能少 .

EDIT

正如Daniel所建议的那样,我使用了numpy.ascontiguousarray,它适用于1D numpy数组,这就是我所做的:

c_array = numpy.ascontiguousarray(array,dtype=numpy.uint32)

但是当我尝试2D阵列的类似方法时,它不起作用,这是我尝试的:

c_array = numpy.ascontiguousarray(array,dtype=numpy.ndarray)

当我使用它时,python崩溃了 . 我在这做错了什么?

1 回答

  • 2

    最快的方法是,根本不需要转换数组 . 此代码也适用于列表和元组:

    c_array = numpy.ascontiguousarray(param, dtype=int)
    pointer = c_array.ctypes.data_as(ctypes.c_void_p)
    

相关问题