前言
深度图的用途有遮挡、碰撞、距离测量、重新照明场景、替换现有物体纹理、设置背景或前景的景深效果、设置雨和雪的环境效果等。
一、遮挡效果
左图是虚拟Android机器人和行李箱重叠,右图是机器人被遮挡,看起来更加逼真。
二、支持的设备
深度API只在部分设备上可用,或者说ARCore支持的设备不一定支持深度API。
支持深度API的设备请见本文末尾。
三、深度图
深度API使用“depth from motion”(从运动获取深度)算法来创建深度图。算法从不同角度拍摄多个图像,并将其进行比较,估计用户移动设备时,设备与每个像素的距离。
如果设备有深度传感器,比如ToF摄像头,则数据会被包含在处理后的深度中。此时,即使相机不移动也可以使用深度。深度传感器可以在几乎没有特征的表面或物体移动的场景提供更好的深度。
下方是墙上挂着自行车的走廊,左图是相机图像,右图是深度图的可视化。
四、运动要求
当设备上没有深度传感器(比如ToF摄像头)时,深度API使用SLAM(同步定位和地图构建)。
注:SLAM是一种将相机图像和设备IMU的惯性测量值结合在一起,以估计相机相对于现实世界的位置和方向的技术。
“depth from motion”(从运动获取深度)算法将成对的相机图像视为静态场景的两次观察。如果场景中某些部分移动了,则场景的静态部分有准确估计的深度,但移动部分不会。
没有深度传感器时,用户需要移动设备几厘米。
五、提供的深度范围
提供的深度范围从0米到8米,最佳深度范围为从0.5米到5米。随着与相机的距离增加,误差会增大。
没有深度传感器时,很少特征或没有特征的表面(比如白墙)的深度会不准确。
六、深度图的4个API
Config.setDepthMode:设置使用深度API的模式。并非所有支持ARCore的设备都支持深度API模式。
Config.getDepthMode:返回当前的深度API配置值(自动或禁用)。“自动”表示:在支持的设备上,根据硬件和软件估算深度。可用来源是运动和深度相机。 此选项会增加大量的计算负担。
Session.isDepthModeSupported:检查当前设备和当前摄像头是否支持深度API模式。
Frame.acquireDepthImage:尝试获取与当前帧对应的深度图像。
深度图像每个像素包含到相机的距离,单位为毫米。
使用深度API的示例代码
// 1.检查是否支持深度API
boolean isDepthSupported = session.isDepthModeSupported(Config.DepthMode.AUTOMATIC);
if (isDepthSupported) {
// 2.设置使用深度API
config.setDepthMode(Config.DepthMode.AUTOMATIC);
}
session.configure(config);
try {
// 3.获取深度图像
Image depthImage = frame.acquireDepthImage();
}
catch (NotYetAvailableException e) {
}
七、遮挡效果的渲染方法
方法1:使用深度图确定虚拟内容中的某些像素是否可见,如果看不见像素,则对其裁剪。
方法2:进行两遍渲染。第一遍将虚拟内容渲染到缓冲区,第二遍使用深度图将虚拟内容和相机图像组合在一起。这种方法可以不使用着色器。
注:着色器是一种实现图像渲染的可编辑程序,需要3D图形开发知识。
2种方法的效率取决于场景的复杂性和应用程序自身的限制。
八、支持深度API的设备清单
从ARCore 1.18版开始,新增深度API。只有部分设备支持深度API。
注:这个设备清单仅表示ARCore 1.18版的支持情况,没有进入清单的新款或旧款手机,可能未来被加入ARCore新版本中。
以下设备是从《ARCore supported devices》中备注的“Supports Depth API”筛选得到。
1、Huawei
Honor 10、Nova 3、Nova 4、P20、P30、P30 Pro
2、Oppo
Reno Ace
3、Samsung
Galaxy S9、Galaxy S9+、Galaxy S10e、Galaxy S10、Galaxy S10+
4、Sony
Xperia XZ3
5、一加
OnePlus 7、OnePlus 7 Pro
(完)