我正在使用 Cython 从 USB 摄像头抓取图像并将它们转换为返回给调用者的 PIL 图像。
图像的数据位于图像抓取函数返回的结构的“convert_buffer”成员所指向的字符数组中:
struct FlyCaptureImage:
/// stuff
char * convert_buffer
/// more stuff
现在,我正在这样做以将其转换为 PIL 图像:
cdef unsigned char *convert_buffer
cdef Py_ssize_t byte_length
cdef bytes py_string
// get the number of bytes into a Py_ssize_t type
byte_length = count
// slice the char array so it looks like a Python str type
py_string = convert_buffer[:byte_length]
// create the PIL image from the python string
pil_image = PILImage.fromstring('RGB', (width, height), py_string)
将数据转换为 python 字符串的过程需要 2 毫秒,听起来可能是零复制事件。是否可以让 PIL 仅从相机 API 提供的 char * 图像数据指针创建我的图像?
最佳答案
从 PIL 1.1.4 开始, Image.frombuffer
方法支持零拷贝:
问题是您的相机数据似乎是 24 位 RGB,而 PIL 需要 32 位 RGBA/RGBX。你能控制来自相机 API 的像素格式吗?
如果没有,使用 Image.frombuffer
仍然可能有优势,因为它会接受 buffer
而不是要求您从像素数据构建 python 字符串。
编辑:查看 frombuffer
的源代码,它是 fromstring
上的轻量级包装,零拷贝需要 Image._MAPMODES
列表(即 RGBX)中的像素格式。至少,您必须将 RGB 数据复制/转换到 RGBX 缓冲区以获得零复制兼容像素格式。
我没有更好的方法将原始字节放入 PIL,但这里有一些有趣的引用资料:
关于python - 你能用 Cython 创建一个 PIL 镜像而不需要重复复制内存吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11172929/