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

标签 python c numpy ctypes python-c-extension

您好,我正在使用 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/

相关文章:

python - 正确使用 numpy.vectorize

python - 根据 MultiIndex DataFrame 中的第一级列删除重复项

Python,人类可读字节转换

c - 这个C BNF语法不完整吗?

c - 嵌套 'if' 语句不起作用

python - 对从 np.where 获得的索引应用偏移量

python - 包含数字的列表

python - 在 Numpy genfromtxt 中加载日期

c - 随机猜谜游戏(整数)- 输入字符串时出现错误

python - 如果来自子字符串列表,则从列表中删除字符串