我正在使用 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,但这里有一些有趣的引用资料:

  • Cython automatic type conversions
  • Efficient indexing of objects supporting the Python buffer interface(用于 numpy/PIL)
  • Converting malloc'ed buffers from C to Python without copy using Cython?
  • PyMemoryView_FromMemory (python 3.3)
  • 关于python - 你能用 Cython 创建一个 PIL 镜像而不需要重复复制内存吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11172929/

    10-13 05:30