9

我们正在开发一个使用 ARKit 中人物遮挡的演示应用程序。因为我们想在最终场景中添加视频,所以我们使用SCNPlanes 来渲染视频,使用 aSCNBillboardConstraint确保它们朝向正确的方向。这些视频也是部分透明的,使用SCNMaterial我们应用的自定义着色器(因此一次播放 2 个视频)。

现在我们遇到了一些人的遮挡非常不稳定的问题(见图)。我们用来测试的视频是一个穿着深色裤子和裙子的女人(如果你想知道图像中的黑色是什么)。

我们遇到的问题是遮挡并不总是与人对齐(如图所示),并且并不总是能正确检测到某人的头发。

现在我们的问题是导致这些问题的原因是什么?我们怎样才能改善这些问题,直到它们看起来像这样?我们目前正在探索问题是否是因为我们使用的是飞机,但仅仅使用飞机SCNBox并不能解决问题。

在此处输入图像描述

4

1 回答 1

18

更新日期:2021 年 7 月 4 日

由于新的深度 API和可以以 60 fps 捕获的更高质量的 ZDepth 通道,您可以提高 ARKit 5.0/4.0/3.5 的质量People Occlusion和功能。但是,为此您需要配备激光雷达扫描仪的 iPhone 12 Pro 或 iPad Pro。Object Occlusion

People Occlusion但在 ARKit 3.0 中,除非您使用 Metal 或 MetalKit,否则您无法改进功能。People Occlusion然而,使用 Metal 系列框架在 ARKit 3.0中改进并不容易,相信我。

提示:考虑RealityKitAR QuickLook框架也支持People Occlusion


为什么在使用 People Occlusion 时会出现此问题?

这是由于第五通道的性质——ZDepth通道。我们都知道,渲染的 3D 场景最终图像可以包含 5 个用于数字合成的主要通道 - RedGreenBlueAlphaZDepth

在此处输入图像描述

当然,还有其他有用的渲染通道(也称为 AOV)可用于合成: NormalsMotionVectorsPointPositionUVsDisparity等。但这里我们只对两个主要渲染集感兴趣 -RGBAZDepth.


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对象的边缘。

坦率地说,有一个解决深度问题的有效解决方案——你应该使用 aDeep channel而不是 a ZDepth channel。但是没有一个游戏引擎支持它,因为它Deep channel非常庞大。所以深度通道合成既不适用于游戏引擎,也不适用于 ARKit。唉!

在此处输入图像描述


问题 2. ZDepth 的分辨率

常规ZDepth通道必须以32 位渲染,即使RGBAlpha通道都是8 位的。32 位文件的颜色位深度对 CPU 和 GPU 来说是一个沉重的负担。记住在 ARKit 视口中合成多个图层——这里是前景字符在 3D 模型和背景字符上的合成。你不觉得这对你的设备来说太多了吗,即使这些是在视口分辨率而不是真实屏幕分辨率下合成的?但是,将ZDepth通道渲染为16 位8 位 compresses真实场景的深度,会降低合成质量。

为了减轻 CPU 和 GPU 的负担并节省电池寿命,Apple 工程师决定在捕获阶段使用缩小的 ZDepth 图像,然后将渲染的 ZDepth 图像放大到视口分辨率并使用Alpha 通道(又名分割),然后使用扩张合成操作修复 ZDepth 通道的边缘。因此,这导致了我们可以在您的照片中看到的令人讨厌的人工制品(某种“线索”)。

在此处输入图像描述

在此处输入图像描述

请查看此处演示文稿幻灯片 pdfBringing People into AR


问题 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查看应用程序的示例代码。


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在您的代码中使用实例属性之前,您需要检查设备是否具有 LiDAR 扫描仪。您可以在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)
于 2019-10-10T15:09:33.200 回答