2014-09-23 157 views
0

我有一个控制摄像头的C函数,我试图通过Ctypes将图像缓冲区发送给Python以用于GUI。通过ctypes将C数组传递给python

我可以抓住缓冲区,但我坚持基本上如何让这个工作,我想我可以看看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++) 
    { 
    ... 
    } 
} 

UPDATE:

原来我需要一个指针分配给我的阵列,但它是在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> 
+0

你在返回之前释放了数组?那么你不会在那个地方得到一个无效的地址吗? – Santa 2014-09-23 19:09:52

+0

事实上,这是一个打字错误,这个帖子,很好的捕捉。但是我在实际的代码中没有这个问题。谢谢! – user2221667 2014-09-23 19:13:11

+0

什么不行?你得到的错误是什么?你想做什么,你不知道该怎么做?转换为c_ubyte数组看起来是正确的。从这里的问题,你不清楚你有什么问题。 – 2014-09-23 19:40:08

回答

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位,所以我改变了数据类型。

+0

我试过了,但是我得到:TypeError:对于请求的数组,缓冲区太小。 – user2221667 2014-09-30 19:50:25

+0

然后您的高度,宽度或data_type与您的c_ubyte缓冲区大小不匹配。检查您的缓冲区大小,并将其与您期望的图像进行比较,并确保它们匹配。 – ballsatballsdotballs 2014-10-02 01:08:51