ARFaceTrackingConfiguration:如何区分图片和真实人脸?

Ber*_*lor 7 augmented-reality ios scenekit swift arkit

我们在商店中有几个应用程序,ARFaceTrackingConfiguration用于检测带有 FaceID 摄像头的 iOS 设备中的用户面部。

正如您可能已经看到的那样,ARKit 还会跟踪您放在 iPad Pro/iPhoneX 前的面孔图片,就好像它们是面孔一样。例如,从我们的一个应用程序中拍摄一张照片(复制一个可以为 ARFaceTrackingConfiguration下载并运行 Apple示例应用程序):

音乐天使上的面膜

现在我注意到 ARKit 在内部处理真实人脸的方式与处理人脸图片的方式不同。因为通常(对于ARWorldTrackingConfiguration以及ARFaceTrackingConfiguration)都ARKit试图匹配现实世界的大小和虚拟对象的大小,即 3D 编辑软件中 10x10cm 的对象将匹配相同 10x10cm 的现实世界对象。但是当使用人脸跟踪时,手机检测到异常大小的脸(如上图所示的 4 厘米宽的小脸或脸更大的人的海报)它会缩放 FaceGeometry 就好像检测到的脸是正常大小的头部,即头部宽度的测量值约为 ~14 厘米。然后所有虚拟对象将相应地缩放,这将在现实世界中产生错误的大小。看下一张图:

音乐天使飞行员眼镜

眼镜 3D 模型宽约 14 厘米,但它们仅显示为 4 厘米的物体。

相比之下,如果你把眼镜放在真正的3D脸上,它们会是正确的尺寸,在小人头上(比如12厘米)会稍微大一些,在大人头上(比如16厘米)会稍微大一点太小(因为在这两种情况下它们都是真正的 14 厘米)。

我什至可以看到 ARKit 在以下之间切换:

  1. 仅使用相机图像的平面检测
  2. 使用 FaceID TrueDepth 相机进行人脸检测。

当您将婴儿抱在应用程序前时,这一点尤其突出。对于婴儿的头部,ARKit将首先尝试放大所有内容,使虚拟场景中婴儿的头部为 14 厘米宽,并且眼镜像成人一样适合。然后,通常在头部出现在相机中后 1-2sARFaceTrackingConfiguration会从模式 ( 1 )切换到模式 ( 2 ) 并显示 3D Object 的真实尺寸,从而导致婴儿头戴成人尺寸眼镜的超可爱照片(不是此处显示为 SO 不是用于分享婴儿照片)。

那么,现在问题来了:

有没有办法确定 ARKit 是处于模式1还是模式2

ARG*_*Geo 3

目前 ARKit 3.0 API 中还没有办法做到这一点。

\n\n
\n

ARKit 会话不断从 处的运动传感器、 处的前置 RGB 摄像头以及 处的红外摄像头ARFaceTrackingConfiguration获取数据。TrueDepth 传感器在会话运行时工作。您无法在 ARKit 中手动停止 TrueDepth 传感器。1000 Hz60 Hz15 Hz

\n
\n\n

在此输入图像描述

\n\n

工作距离约为,ARFaceTrackingConfiguration因此15...100 cm您可以在 ARKit 3.0 中有效检测该距离内最多 3 个人脸。但是 ARKit 人脸检测中有一些逻辑错误 \xe2\x80\x93 你可以在跟踪你身后海报上的大脸的同时跟踪你的脸(但海报上的脸是平的,因为它具有等距深度)。因此,规范掩模的比例取决于检测到的人脸的大小(如您之前所说),但 ARKit 无法立即调整该规范掩模(ARFaceGeometry)的比例,因为人脸跟踪非常占用 CPU 资源。

\n\n

Apple 的 TrueDepth 模块的工作距离范围非常窄,因为来自 IR 投影仪的 30K 点必须具有明确的亮度、模糊度、覆盖范围和点大小才能被 ARKit 有效使用。

\n\n

使用此代码,您可以测试 TrueDepth 模块是否参与进程:

\n\n
@available(iOS 13.0, *)\nclass ViewController: UIViewController {\n\n    @IBOutlet var sceneView: ARSCNView!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        sceneView.session.delegate = self\n    }\n}\n\nextension ViewController: ARSessionDelegate {\n\n    func session(_ session: ARSession, didUpdate frame: ARFrame) {\n\n        print(sceneView.session.currentFrame?.capturedDepthData?.depthDataQuality as Any)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

通常,每第四帧打印一次深度数据(但有时间隙大于 4 帧):

\n\n

在此输入图像描述

\n\n

只有一种情况TrueDepth 传感器不会生成 RGB 数据:当您将智能手机移得太靠近海报或太靠近您的脸时 \xe2\x80\x93,因此您只会看到正在打印的nils内容。

\n