从 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 上测试):

我的代码中缺少什么才能使它在 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个像素是无用的。