从 Chrome OS 上的 16 位深度网络摄像头流式传输时图像颜色错误
Wrong image colour when streaming from 16-bit depth webcam on Chrome OS
我想显示来自 USB 热像仪的视频流 - 作为记录,它是 FLIR Lepton PureThermal 2 - 在我的网络应用程序上,运行 在 Chrome OS(版本 85.0.4183.84 - 最新可用)。
起初我假设该设备可以作为标准网络摄像头进行流式传输,所以我想出了以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webcam test</title>
</head>
<body>
<video id="videoElement" width="800" height="600" muted autoplay></video>
</body>
<script type="text/javascript">
let videoElement = document.getElementById('videoElement');
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
let videoDevices = [];
navigator.mediaDevices.enumerateDevices()
.then(devices => {
videoDevices = devices.filter(device => {
if (device.kind !== "videoinput") return;
console.debug(`Identified video input: ${JSON.stringify(device)}`);
return true;
});
let selectedCamera = videoDevices[videoDevices.length - 1]; // usually the thermal camera will be the last one
console.debug(`Streaming device ${JSON.stringify(selectedCamera)}...`);
return navigator.mediaDevices.getUserMedia({
video: {
deviceId: { exact: selectedCamera.deviceId },
width: {exact: 160 }, height: {exact: 120 }, // forcing QQVGA resolution
},
});
})
.then(stream => {
videoElement.srcObject = stream;
videoElement.play();
})
.catch(error => console.error(error));
}
</script>
</html>
上面的代码在 Windows 10 上的任何浏览器上都按预期工作,但我没有得到我在 Chrome OS 上期望的图像。请参阅下面的比较:
仔细一看,Chrome其实是在流什么东西,只是不够清晰而已。改变图像的水平和对比度给我这个:
仅作记录,该代码适用于以下所有浏览器(仅在 Windows 10 上测试):
- Chrome85.0.4183.83
- 火狐 80.0
- 歌剧 70.0.3728.133
- 边缘 85.0.564.41
- Edge Legacy(可能是版本 40)
我的代码中缺少什么才能使它在 Chrome OS 上像在 Windows 上对 Chrome 一样工作?
我通过执行以下操作使其在 Chrome OS 上运行:
- 视频开始播放后,立即将当前帧的字节保存到纹理缓冲区(借助 WebGL)
- 对于帧中的每个像素,将红色通道乘以 65535,返回以厘开尔文为单位的温度
- 将其转换为摄氏度并操纵像素以显示温度范围内的灰度图像
- 在 canvas
上绘制像素
- 请求新帧(重新开始循环)
在此处查看示例代码:https://codesandbox.io/s/upbeat-wood-umo9w?file=/index.html
结果:
特别感谢Aleksandar Stojiljkovic and Kurt Kiefer。
可以通过将自定义着色器应用于纹理来实现相同的结果。
我仍然不确定为什么 Chrome OS 以不同的方式处理视频,所以我已经在 Chromium issue tracker 上提出了一个问题。
如果您设置 160x120,您将获得标准化图像 (RGB888)。
如果你设置160x122,你会得到一个黑白图像(Y16),底部2个像素是无用的。
我想显示来自 USB 热像仪的视频流 - 作为记录,它是 FLIR Lepton PureThermal 2 - 在我的网络应用程序上,运行 在 Chrome OS(版本 85.0.4183.84 - 最新可用)。
起初我假设该设备可以作为标准网络摄像头进行流式传输,所以我想出了以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webcam test</title>
</head>
<body>
<video id="videoElement" width="800" height="600" muted autoplay></video>
</body>
<script type="text/javascript">
let videoElement = document.getElementById('videoElement');
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
let videoDevices = [];
navigator.mediaDevices.enumerateDevices()
.then(devices => {
videoDevices = devices.filter(device => {
if (device.kind !== "videoinput") return;
console.debug(`Identified video input: ${JSON.stringify(device)}`);
return true;
});
let selectedCamera = videoDevices[videoDevices.length - 1]; // usually the thermal camera will be the last one
console.debug(`Streaming device ${JSON.stringify(selectedCamera)}...`);
return navigator.mediaDevices.getUserMedia({
video: {
deviceId: { exact: selectedCamera.deviceId },
width: {exact: 160 }, height: {exact: 120 }, // forcing QQVGA resolution
},
});
})
.then(stream => {
videoElement.srcObject = stream;
videoElement.play();
})
.catch(error => console.error(error));
}
</script>
</html>
上面的代码在 Windows 10 上的任何浏览器上都按预期工作,但我没有得到我在 Chrome OS 上期望的图像。请参阅下面的比较:
仔细一看,Chrome其实是在流什么东西,只是不够清晰而已。改变图像的水平和对比度给我这个:
仅作记录,该代码适用于以下所有浏览器(仅在 Windows 10 上测试):
- Chrome85.0.4183.83
- 火狐 80.0
- 歌剧 70.0.3728.133
- 边缘 85.0.564.41
- Edge Legacy(可能是版本 40)
我的代码中缺少什么才能使它在 Chrome OS 上像在 Windows 上对 Chrome 一样工作?
我通过执行以下操作使其在 Chrome OS 上运行:
- 视频开始播放后,立即将当前帧的字节保存到纹理缓冲区(借助 WebGL)
- 对于帧中的每个像素,将红色通道乘以 65535,返回以厘开尔文为单位的温度
- 将其转换为摄氏度并操纵像素以显示温度范围内的灰度图像
- 在 canvas 上绘制像素
- 请求新帧(重新开始循环)
在此处查看示例代码:https://codesandbox.io/s/upbeat-wood-umo9w?file=/index.html
结果:
特别感谢Aleksandar Stojiljkovic and Kurt Kiefer。
可以通过将自定义着色器应用于纹理来实现相同的结果。
我仍然不确定为什么 Chrome OS 以不同的方式处理视频,所以我已经在 Chromium issue tracker 上提出了一个问题。
如果您设置 160x120,您将获得标准化图像 (RGB888)。
如果你设置160x122,你会得到一个黑白图像(Y16),底部2个像素是无用的。