首页 > 解决方案 > 如何使用外部 USB 相机数据正确格式化 PIL.Image.frombytes

问题描述

我很难读取从 USB 相机接收到的数据并正确显示。我成功了,但我担心我做错了什么,因为我的解决方案很老套。

我正在使用的 USB 摄像头 ( ui-1640le ) 返回一个我想要显示的字节数组。我用PIL.Image.frombytes("RGB", (imageWidth, imageHeight), image_bytes) 了但是我得到的图像是黑白的并且重复了: 图像结果

我尝试使用该"L"格式。PIL.Image.frombytes("L", (imageWidth, imageHeight), image_bytes)看看会发生什么,我得到了:这张黑白图像。除了是黑白的,图像看起来是正确的,并且该函数只读取了三分之一的数据。

所以我用这段代码对数据进行了逆向工程:

# Reorder the bytes structure
x=[]
for i in range(width*height):
    x += [img[i],img[i+width*height],img[i+2*width*height]]
image_bytes = bytes(x)


# Create a PIL Image
im = PIL.Image.frombytes("RGB", (imageWidth, imageHeight), image_bytes)

# Not sure why the image is flipped, but this fixes it
im.rotate(-90).transpose(PIL.Image.FLIP_LEFT_RIGHT).show()

之后,我终于得到了应有的图片:最终图片

这个解决方案对读取相机输入是否有意义,我做错了什么吗?我缺少更直接的方法吗?

标签: pythonimage-processingpython-imaging-library

解决方案


虽然您将平面交错数据打包成像素交错数据的方法可行,但您几乎肯定会发现 Numpy 方法要快几十倍。

首先,我将综合您的输入数据:

import numpy as np

# Height, width and bytes per image channel
h,w = 100,256
bpc = h * w

# Now make the first (red) plane = 255, the second (green) plane = 127 and the final (blue) plane = 0
img = bytes(b"\xff"*bpc) + bytes(b"\x7f"*bpc) + bytes(b"\x00"*bpc)

因此,img现在应该是您可能获得的具有代表性的 100x256 橙色图像。然后我将交错数据并使用 Numpy 制作这样的 PIL 图像:

from PIL import Image

# Make a Numpy array for each channel's pixels
R = np.frombuffer(img, dtype=np.uint8, count=bpc).reshape((h,w))  
G = np.frombuffer(img, dtype=np.uint8, count=bpc, offset=bpc).reshape((h,w))  
B = np.frombuffer(img, dtype=np.uint8, count=bpc, offset=2*bpc).reshape((h,w))

# Interleave the pixels from RRRRRRGGGGGGBBBBBB to RGBRGBRGBRGBRGB
RGB = np.dstack((R,G,B))

# Make PIL Image from Numpy array
pImage = Image.fromarray(RGB)

在我的机器上这需要 30 微秒,而for循环需要 7 毫秒,因此速度快了 230 倍。

在此处输入图像描述

关键词:Python、Numpy、PIL、图像处理、交错、交错、去交错、平面、按像素、按平面、打包、解包。


推荐阅读