python - 如何使用外部 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()
之后,我终于得到了应有的图片:最终图片
这个解决方案对读取相机输入是否有意义,我做错了什么吗?我缺少更直接的方法吗?
解决方案
虽然您将平面交错数据打包成像素交错数据的方法可行,但您几乎肯定会发现 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、图像处理、交错、交错、去交错、平面、按像素、按平面、打包、解包。
推荐阅读
- c# - C# WPF 与 CefSharp 在 VirtualBox 中崩溃
- php - SQL 查询不显示每个子类别中的产品
- ios - 对于 Cordova 应用内购买,沙盒“确认购买”屏幕是否与商店相同?
- wordpress - “外部化” TimberSite 方法的正确方法是什么?
- list - Kotlin:以功能方式组合列表中的某些元素
- node.js - 使用 socket.io 和 node.js 请求“未授权”
- python - 需要查找两个系列之间的总和值的任何组合是否超过阈值
- git - 有没有办法可以锁定文件在 git master 分支上被修改?
- mysql - 服务器返回无效的时区。转到高级选项卡并手动设置 servertimezone 属性
- powershell - 远程 Powershell 脚本导致 Selenium 超时