python - 在 C 和 NumPy 数组中的数据缓冲区之间进行转换,为 Python 接口(interface)包装 C 程序的最佳方法?

标签 python c numpy swig

我们有一个用 C/C++ 编写的预先存在的大型图像库,具有预先存在的图像类型。我们想将它与 Python 连接起来。例如,我们知道如何使用 SWIG 来做大部分事情,但我们希望我们的界面使用 NumPy 而不是本地开发的结构类型来存储我们的图像。

有没有人有如何做到这一点的例子?网络上有将 NumPy 连接到裸指针的示例。我们如何将 NumPy 连接到像这样的现有 C 类型结构:

typedef struct xvimage {

    int nx, ny, nz, nt ; // dimensions

    enum {PIX_UINT8, PIX_INT16, PIX_UINT16, PIX_INT32, PIX_FLOAT, PIX_DOUBLE} ; // type

    void *data;

} xvimage;

最佳答案

主要有以下三种方式:

  1. 从图像缓冲区复制到 NumPy 数组,反之亦然。当给定一个 C/C++ 图像时,创建一个 NumPy 数组并复制数据,当给定一个 NumPy 数组时,创建一个 C/C++ 图像并复制数据。

  2. NumPy 数组作为 C 数据指针的包装器。创建一个带有给定数据指针的 N​​umPy 数组。确保保存数据指针的 C/C++ 镜像比 NumPy 数组的生命周期更长。 NumPy 数组的生命周期可以更短,因为在这种情况下它不会尝试删除数据。

  3. C/C++ 图像缓冲区作为 NumPy 数组指针的包装器。创建一个 NumPy 数组并提取数据指针,然后使用它来就地操作 NumPy 数组。通过持有 Python 引用确保 NumPy 数组存在足够长的时间。

这些中的每一个都可以在 SWIG 类型映射中实现。

在任何情况下,您都需要将类型转换为 NumPy 类型(NPY_UINT8,..)并将图像尺寸存储在 npy_intp * 中。

要创建 NumPy 数组,请使用 PyArray_NewPyArray_SimpleNewPyArray_SimpleNewFromData ( Array API ) 并指定所需的标志,如 Fortran 风格的连续或者任何对你方便的东西。您可以使用 PyArray_NewPyArray_SimpleNewFromData 提供自己的数据指针。

返回值是一个PyObject*,可以安全地转换为PyArrayObject*(或之前执行一个PyArray_Check)和数据指针由 PyArray_DATA ( Array API ) 提取,它返回一个 void *,然后您可以将其转换为所需的类型。然后您可以根据需要执行复制或就地修改。

要添加对 Python 对象的引用,请使用 Py_INCREFPy_DECREF ( doc ),以防 NumPy 数组被过早删除。

如果您想在 Python 对象即将被垃圾回收时收到通知,请通过 PyWeakref_NewRef (doc) 使用弱引用。

关于python - 在 C 和 NumPy 数组中的数据缓冲区之间进行转换,为 Python 接口(interface)包装 C 程序的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36505699/

相关文章:

Python Numpy : Random number in a loop

python - PyCharm 中是否有突出显示代码块的快捷方式

python - 方法的 __file__ 属性如何成为类而不是实例?

python - URLconf 不适用于类似的 URL

c - pthreads:使用多线程计算连续素数

c - 为什么 sizeof(msg) 比字符串短?

c - 这个程序计算 5 位数字的总和是否正确

python - NumPy 中矩阵列的 nanmean

python - 在 numpy 中对按变量分组的行取平均值

python - 通过 SSH 执行远程 python 脚本