我有一个控制相机的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>
答案 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位,所以我改变了数据类型。