深度图本质上是一个图画(或图画通道),它包括了与场景中物体表面与给定视角(在这种情况下,相机自身)的距离有关的信息,在该图画中的每个像素。深度图是各种核算机图形和核算机视觉使用的基本组成部分,如增强实际、肖像模式和三维重建。尽管最近ARCore深度API在深度感应能力方面取得了进展,但网络上的大多数相片依然缺少相关的深度图。再加上网络社区的用户对在JavaScript中拥有深度功能以增强现有网络使用的爱好日益稠密,例如将图画带入实际,将实时AR效果使用于人脸和身体,甚至重建物品以用于VR环境,这些都有助于构成你今天看到的路径。

今天,咱们将介绍深度API,这是TensorFlow.js的第一个深度估量API。经过这个新的API,咱们还引入了第一个用于肖像的深度模型,ARPortraitDepth,它为一个单一的肖像图画估量深度图。为了展现深度信息许多或许的用途之一,咱们还展现了一个核算拍摄使用,3D photo,它利用猜测的深度,在给定的肖像图画上实现了3D视差效果。试试下面的现场演示,每个人都能够轻松地使他们的社交媒体资料相片变成3D,如下图所示。

自己试试3D人像演示吧吧

ARPortraitDepth:单一图画深度估量

人像深度API的核心是一个深度学习模型,名为ARPortraitDepth,它将单色人像图画作为输入并产生深度图。为了进步核算功率,咱们采用了一个轻量级的U-Net架构。如下图所示,编码器逐步将图画或特征图的分辨率降低一半,而解码器将特征分辨率进步到与输入相同。来自编码器的深度学习特征被串联到解码器中具有相同空间分辨率的相应层,以带来用于深度估量的高分辨率信号。在练习过程中,咱们逼迫解码器在每一层产生分辨率越来越高的深度猜测,并为每一层添加一个与地面真相有关的损失。根据经历,这有助于解码器经过逐步添加细节来猜测精确的深度。

丰富多样的练习数据关于机器学习模型实现整体的杰出功能,例如精确性和鲁棒性,是至关重要的。咱们用不同的相机配置,如焦距、相机姿态,从高质量功能的捕捉系统捕捉到的三维数字人类中,组成烘托成对的彩色和深度图画,并使用高动态范围环境照度图进行从头照明增强,以添加彩色图画的真实性和多样性,如面部的阴影。咱们还使用装备了前置深度传感器的手机收集真实数据,例如谷歌Pixel 4,其间深度质量作为练习的根底事实,并不像咱们的组成数据那样精确和完好,但彩色图画在野外的图画上运行时能够有效地进步咱们模型的功能。

为了增强对布景变化的鲁棒性,在实践中,咱们在将图画送入深度估量的神经网络之前,用MediaPipe和TensorFlow.js运行一个现成的人体分割模型。

人像深度模型能够实现一大批以人体为导向的创意使用,能够推动下一代网络使用。咱们向读者引荐ARCore深度实验室,以取得更多创意。

关于3D相片使用程序,咱们创建了一个高功能的烘托管道。它首要使用TensorFlow.js现有的身体分割API生成一个分割的面具。接下来,咱们将遮罩后的肖像传入肖像深度API,在GPU上取得深度图。最终,咱们在three.js中生成一个深度网格,极点以规则的网格摆放,并经过从头投影相应的深度值进行位移(生成深度网格见下图)。最后,咱们将纹路投影使用于深度网格,并将摄像机环绕Z轴旋转一圈。用户能够下载GIF或WebM格式的动画。

人像深度API的装置

人像深度API现在是作为新深度API的一个变体供给的。

要装置API和运行时库,你能够使用

经过NPM:

yarn add @tensorflow/tfjs-core @tensorflow/tfjs-backend-webgl
yarn add @tensorflow/tfjs-converter
yarn add @tensorflow-models/body-segmentation
yarn add @tensorflow-models/depth-estimation

在你的JS代码中引证API,这取决于你怎么装置该库。

假如经过脚本标签装置,你能够经过全局命名空间depthEstimation 来引证该库。

假如经过NPM装置,你需求先导入库:

import '@tensorflow/tfjs-backend-core';
import '@tensorflow/tfjs-backend-webgl';
import '@tensorflow/tfjs-converter';
import '@tensorflow-models/body-segmentation;
import * as depthEstimation from '@tensorflow-models/depth-estimation;

自己试试吧!

首要,你需求创建一个预算器:

const model = depthEstimation.SupportedModels.ARPortraitDepth;
    estimator = await depthEstimation.createEstimator(model);
    const video = document.getElementById('video');
    const depthMap = await estimator.estimateDepth(video);

一旦你有了一个估量器,你就能够传入视频流、静态图画或TensorFlow.js的张量来估量深度:

const video = document.getElementById('video');
    const estimationConfig = {
      minDepth: 0, // The minimum depth value outputted by the estimator.
      maxDepth: 1, // The maximum depth value outputted by the estimator.
    };
   const depthMap = await estimator.estimateDepth(video, estimationConfig);

怎么使用输出?

上面的depthMap 成果包括图画中每个像素的深度值。

depthMap 是一个存储底层深度值的目标。然后,你能够利用所供给的异步转化函数,如toCanvasImageSourcetoArray ,和toTensor ,这取决于你想要的输出类型,以进步功率。

应该留意的是,不同的模型对数据有不同的内部表明。因而,从一种方式转化到另一种方式或许是贵重的。以功率的名义,你能够调用getUnderlyingType ,以确认深度图已经是什么方式,所以你能够选择保持相同的方式以取得更快的成果。

depthMap的语义如下:深度图的大小与输入图画相同。关于阵列和张量表明,每个像素有一个深度值。关于CanvasImageSource ,绿色和蓝色通道总是被设置为0,而赤色通道存储深度值。

请看下面的输出片段的比如:

  {
    toCanvasImageSource(): ...
    toArray(): ...
    toTensor(): ...
    getUnderlyingType(): ...
  }

浏览器功能

人像深度模型

MacBook M1 Pro 2021年。

(FPS)

iPhone 13 Pro

(FPS)

台式电脑

英特尔i9-10900K。Nvidia GTX 1070 GPU。

(FPS)

TFJS运行时间

带有WebGL后端。

51

22

47