如何改善 ARKit 3.0 中的人物遮挡
Posted
技术标签:
【中文标题】如何改善 ARKit 3.0 中的人物遮挡【英文标题】:How to improve People Occlusion in ARKit 3.0 【发布时间】:2020-02-04 17:45:17 【问题描述】:我们正在开发一个使用 ARKit 中人物遮挡的演示应用。因为我们想在最终场景中添加视频,所以我们使用SCNPlane
s 使用SCNBillboardConstraint
渲染视频,以确保它们朝向正确的方向。这些视频也是部分透明的,在我们应用的 SCNMaterial
上使用自定义着色器(因此一次播放 2 个视频)。
现在我们遇到了一些人的遮挡非常不稳定的问题(见图)。我们用来测试的视频是一个穿着深色裤子和裙子的女人(如果你想知道图片中的黑色是什么)。
我们遇到的问题是遮挡并不总是与人对齐(如图中所示),并且并不总是能正确检测到某人的头发。
现在我们的问题是导致这些问题的原因是什么?我们怎样才能改善这些问题,直到它们看起来像this?我们目前正在探索问题是否是因为我们使用的是飞机,但仅仅使用SCNBox
并不能解决问题。
【问题讨论】:
【参考方案1】:更新日期:2021 年 7 月 4 日。
借助新的 Depth API 和更高质量的 ZDepth 通道,您可以提高 ARKit 5.0/4.0/3.5 中 People Occlusion
和 Object Occlusion
功能的质量可以以 60 fps 的速度拍摄。但是,为此您需要配备激光雷达扫描仪的 iPhone 12 Pro 或 iPad Pro。
但在 ARKit 3.0 中,您无法改进 People Occlusion
功能,除非您使用 Metal 或 MetalKit。然而,使用 Metal 系列框架在 ARKit 3.0 中改进 People Occlusion
并不容易,相信我。
提示:请考虑 RealityKit 和 AR QuickLook 框架也支持 People Occlusion
。
为什么在使用 People Occlusion 时会出现此问题?
这是由于第五频道的性质 - ZDepth
频道。我们都知道,渲染后的 3D 场景最终图像可以包含 5 个用于数字合成的主要通道——Red
、Green
、Blue
strong>、Alpha
和 ZDepth
。
当然,还有其他有用的渲染通道(也称为 AOV)可用于合成:Normals
、MotionVectors
、PointPosition
、UVs
、Disparity
等。但这里我们只对两个主要的渲染集感兴趣——RGBA
strong> 和 ZDepth
。
ZDepth 通道在 ARKit 3.0 中存在三个严重缺陷。
问题1. ZDepth的锯齿和抗锯齿。
在任何高端软件(如 Nuke、Fusion、Maya 或 Houdini)中渲染 ZDepth 通道,默认情况下会导致锯齿状边缘或所谓的锯齿状边缘。游戏引擎也不例外——SceneKit、RealityKit、Unity、Unreal 或 Stingray 也有这个问题。
当然,您可以说,在渲染之前我们必须打开一个名为Anti-aliasing
的功能。而且,是的,它几乎适用于所有通道,但不适用于 ZDepth。 ZDepth 的问题是——如果anti-aliased
,每个前景对象(特别是如果它是透明的)的边界像素被“转换”为背景对象。换句话说,FG和BG的像素混合在FG对象的边缘。
坦率地说,有一个解决深度问题的有效解决方案 - 您应该使用 Deep channel
而不是 ZDepth channel
。但是没有一个游戏引擎支持它,因为 Deep channel
非常庞大。所以深度通道合成既不适用于游戏引擎,也不适用于 ARKit。唉!
问题2。ZDepth的分辨率。
常规 ZDepth 通道必须以 32 位 呈现,即使 RGB 和 Alpha 通道都是仅限 8 位。 32 位文件的颜色位深度对 CPU 和 GPU 来说是一个沉重的负担。记住在 ARKit 视口中合成多个图层——这里是前景字符在 3D 模型和背景字符上的合成。你不觉得这对你的设备来说太多了吗,即使这些合成在viewport resolution而不是真正的屏幕rez?但是,以 16-bit 或 8-bit compresses
真实场景的深度渲染 ZDepth 通道,会降低合成质量。
为了减轻 CPU 和 GPU 的负担并延长电池寿命,Apple 工程师决定在捕获阶段使用缩小的 ZDepth 图像,然后将渲染的 ZDepth 图像放大到视口分辨率和 Stencil 它使用 Alpha 通道(也称为分段),然后使用 Dilate 合成操作修复 ZDepth 通道的边缘。因此,这导致了我们可以在您的照片中看到的令人讨厌的人工制品(某种“线索”)。
请看Bringing People into AR
here的Presentation Slides pdf。
问题3.ZDepth的帧率。
第三个问题源于 ARKit 以 60 fps 的速度工作。仅降低 ZDepth 图像分辨率并不能完全解决问题。因此,Apple 工程师的下一个合乎逻辑的步骤是 – 在 ARKit 3.0 中将 ZDepth 的帧速率降低到 15 fps。然而,最新版本的 ARKit 5.0 以 60 fps 的速度捕获 ZDepth 通道,这大大提高了人物遮挡和物体遮挡的质量。但在 ARKit 3.0 中,这也带来了伪影(ZDepth 通道的某种“丢帧”会导致“轨迹”效果)。
当您使用类型属性时,您无法更改最终合成图像的质量:
static var personSegmentationWithDepth: ARConfiguration.FrameSemantics get
因为它是一个可获取的属性,并且在 ARKit 3.0 中没有 ZDepth 质量设置。
当然,如果你想在 ARKit 3.0 中增加 ZDepth 通道的帧速率,你应该实现在数字合成中发现的 帧插值技术(中间帧是计算机生成的)那些):
但是这种帧插值技术不仅占用大量 CPU,而且非常耗时,因为我们需要每秒生成 45 个额外的 32 位 ZDepth 帧(45 个插值 + 15 个实际 = 60 帧每秒)。
我相信有人可能会通过使用 Metal 开发代码来改进 ARKit 3.0 中的 ZDepth 合成功能,但现在这是一个真正的挑战!
您必须查看
People Occlusion in Custom Renderers
应用程序here的示例代码。
ARKit 5.0 和 LiDAR 扫描仪支持
在 ARKit 5.0、ARKit 4.0 和 ARKit 3.5 中,支持 LiDAR(Light Detection And Ranging
扫描仪)。 LiDAR 扫描仪提高了人物遮挡功能的质量和速度,因为 ZDepth 通道的质量更高,即使您在跟踪周围环境时没有物理移动。 LiDAR 系统还可以帮助您绘制墙壁、天花板、地板和家具的地图,以快速获得真实世界表面的虚拟网格,以便与之动态交互,或者简单地在其上定位 3d 对象(甚至是部分遮挡的 3d 对象)。具有 LiDAR 扫描仪的小工具可以实现无与伦比的精度,以检索真实世界表面的位置。通过考虑网格,光线投射可以与非平面表面或完全没有特征的表面相交,例如白墙或光线不足的墙。
要激活sceneReconstruction
选项,请使用以下代码:
let arView = ARView(frame: .zero)
arView.automaticallyConfigureSession = false
let config = ARWorldTrackingConfiguration()
config.sceneReconstruction = .meshWithClassification
arView.debugOptions.insert([.showSceneUnderstanding, .showAnchorGeometry])
arView.environment.sceneUnderstanding.options.insert([.occlusion,
.collision,
.physics])
arView.session.run(config)
但在您的代码中使用sceneReconstruction
实例属性之前,您需要检查设备是否具有激光雷达扫描仪。您可以在AppDelegate.swift
文件中进行操作:
import ARKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
guard ARWorldTrackingConfiguration.supportsSceneReconstruction(.meshWithClassification)
else
fatalError("Scene reconstruction requires a device with a LiDAR Scanner.")
return true
RealityKit 2.0
在 iPhone 12 Pro 或 iPad Pro 上使用 RealityKit 2.0 应用程序时,您有多个遮挡选项 - ARKit 5.0 中提供相同的选项 - 改进 People Occlusion
, Object Occlusion
(例如家具或墙壁)和Face Occlusion
。要在 RealityKit 2.0 中打开遮挡,请使用以下代码:
arView.environment.sceneUnderstanding.options.insert(.occlusion)
【讨论】:
我并没有真正期待一个更适合苹果公司如何改进它的答案,但我想你的观点是有效的。我们只需要稍等一下,直到他们采纳您的一些建议(或者直到知道 Metal 和渲染管道的人创建 Metal 程序来正确地进行人员遮挡) 您链接的论文表明深度图像不抗锯齿深度信息。特别是,您的第二个数字似乎来自论文,被错误引用。在论文中,图的两侧代表深度通道,但左侧说明了为什么对深度通道进行抗锯齿没有意义。以上是关于如何改善 ARKit 3.0 中的人物遮挡的主要内容,如果未能解决你的问题,请参考以下文章
unity人物第一人称视角制作角色身体遮挡主镜头去掉方法,用VFX自制子弹拖尾效果。