通过ctypes将C数组传递给python

时间:2014-09-23 19:05:37

标签: python c arrays numpy

我有一个控制相机的C函数,我试图通过Ctypes将图像缓冲区发送到Python,以便在GUI中使用。

我可以抓住缓冲区,但我基本上坚持如何让它工作,我想我可以看看numpy-c api,但它看起来很混乱。

到目前为止,我已尝试过以下内容:

创建一个C数组(我猜它是通过指针引用),类似于:

   UINT16 * MyFunction()
    {

        ...grab image... and return Buffer

        size = 2088 * 2080 * sizeof( UINT16);
        array = (BYTE*) malloc(size);
        API_Write_to_buffer(Buffer, 0, array, size);

        API_Free_Buffer(Buffer);


        return array;
    }   

我可以尝试在python中返回数组:

Data = MyFunction() 
array = (c_ubyte * size).from_address(addressof(Data.contents))

其中MyFunction()如下所示:

def MyFunction():

    MyFunction= lib.MyFunction
    MyFunction.restype = POINTER(c_ubyte)
    img_arr = MyFunction()
    return img_arr

另一种选择是使用指针逐行读取:

for(i=0;i<Width;i++)
{
    Ptr = (UINT16*)(bufferPointer + i*bufferWidth);
    for(j=0;j<Height;j++)
    {
    ...
    }
}

更新:

事实证明我需要为我的数组指定一个指针,但它是C中的UINT16。当我尝试将数组放入一个numpy数组时,python崩溃了。 我可以从包装函数返回这个:

def Grab(nframes):

    Grab= 2112 * 2088 * 8   (size of frame width * height * pixelDepth)
    Grab= lib.MyFunction
    Grab.argtypes = [c_uint32]
    Grab.restype = POINTER(c_uint16 * array_length)
    r = Grab(nframes)
    return r

调用函数如下所示:

Data = Grab(1)
print Data

返回此内容:

<__main__.LP_c_ushort_Array_4409856 object at 0x000000000436FE48>

1 个答案:

答案 0 :(得分:1)

假设您有一个c_ubyte数组img_buffer,它有一个width和一个height,因为它是一个图像。我将假设你已经拥有它,因为它看起来像你的代码。

您对c_ubyte数组的强制转换应如下所示:

img_buffer = (c_ubyte * (height * bytes_per_pixel) *
         (width * bytes_per_pixel)).from_address(addressof(data.contents))

您可以使用numpy将其转换为ndarray:

import numpy as np

img = np.ndarray(buffer=img_buffer, dtype=np.uint16, shape=(width, height, 1))

获得ndarray后,您可以使用PIL或matplotlib或OpenCV来显示它。

编辑:看到你的图像是16位,所以我改变了数据类型。