如何改善 ARKit 3.0 中的人物遮挡

Posted

技术标签:

【中文标题】如何改善 ARKit 3.0 中的人物遮挡【英文标题】:How to improve People Occlusion in ARKit 3.0 【发布时间】:2020-02-04 17:45:17 【问题描述】:

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

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

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

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

【问题讨论】:

【参考方案1】:

更新日期:2021 年 7 月 4 日

借助新的 Depth API 和更高质量的 ZDepth 通道,您可以提高 ARKit 5.0/4.0/3.5 中 People OcclusionObject Occlusion 功能的质量可以以 60 fps 的速度拍摄。但是,为此您需要配备激光雷达扫描仪的 iPhone 12 Pro 或 iPad Pro。

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

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

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

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

当然,还有其他有用的渲染通道(也称为 AOV)可用于合成:NormalsMotionVectorsPointPosition UVsDisparity等。但这里我们只对两个主要的渲染集感兴趣——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 位 呈现,即使 RGBAlpha 通道都是仅限 8 位。 32 位文件的颜色位深度对 CPU 和 GPU 来说是一个沉重的负担。记住在 ARKit 视口中合成多个图层——这里是前景字符在 3D 模型和背景字符上的合成。你不觉得这对你的设备来说太多了吗,即使这些合成在viewport resolution而不是真正的屏幕rez?但是,以 16-bit8-bit compresses 真实场景的深度渲染 ZDepth 通道,会降低合成质量。

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

请看Bringing People into ARhere的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 OcclusionObject Occlusion(例如家具或墙壁)和Face Occlusion。要在 RealityKit 2.0 中打开遮挡,请使用以下代码:

arView.environment.sceneUnderstanding.options.insert(.occlusion)

【讨论】:

我并没有真正期待一个更适合苹果公司如何改进它的答案,但我想你的观点是有效的。我们只需要稍等一下,直到他们采纳您的一些建议(或者直到知道 Metal 和渲染管道的人创建 Metal 程序来正确地进行人员遮挡) 您链接的论文表明深度图像抗锯齿深度信息。特别是,您的第二个数字似乎来自论文,被错误引用。在论文中,图的两侧代表深度通道,但左侧说明了为什么对深度通道进行抗锯齿没有意义。

以上是关于如何改善 ARKit 3.0 中的人物遮挡的主要内容,如果未能解决你的问题,请参考以下文章

ARKit - 环境遮挡

如何去掉图片上的遮挡物?

unity人物第一人称视角制作角色身体遮挡主镜头去掉方法,用VFX自制子弹拖尾效果。

winform窗体程序最大化时遮挡屏幕任务栏的设置

如何在不像 Whatsapp 那样遮挡整个屏幕的情况下禁用表格视图?

教你30秒去掉图片上的遮挡方法,怎么把照片上的遮挡物去掉!