是否可以从 ARFrame 访问多个摄像头?

Is it possible to access multiple cameras from ARFrame?

我有一个 ARSession 使用 ARWorldTrackingConfiguration 作为其配置的一部分。我还通过以下方式启用了面部跟踪:

configuration.userFaceTrackingEnabled = true

func session(_ session: ARSession, didUpdate frame: ARFrame)委托方法中,我可以成功从面向世界的相机中获取frame.capturedImage,但似乎没有办法从面部访问框架-面对相机。

我的这个假设正确吗?

如果是这样,在同时使用面部和世界跟踪时,是否有其他方法可以访问两个摄像头的帧?

大约两个同时的 ARConfigurations

通常,一个 ARSession 一次只能 运行 一个 ARConfiguration。但有一个例外:我们可以在 World 跟踪配置中使用 Face 跟踪配置。但是,ARWorldTrackingConfiguration 在这种情况下是一个“主要”(因此 Face 跟踪是一个“补充”配置)。

两个摄像头(后置和前置)每秒产生60个ARFrame,包含RGB、Depth、anchors、轴、特征点等。每个摄像头都有它自己的ARFrame,什么可以用于定义内部和外部ARCamera参数(如3x3相机矩阵或4x4变换矩阵)。

@NSCopying var currentFrame: ARFrame? { get }

但是,在 ARKit 5.0 中,如果您使用激活的实例 运行ning 世界跟踪配置 属性 userFaceTrackingEnabled,您只能访问来自后置摄像头的 ARFrame – 在无法访问来自前置摄像头的同步 ARFrames 的那一刻。

let config = ARWorldTrackingConfiguration()

if ARWorldTrackingConfiguration.supportsUserFaceTracking {
    config.userFaceTrackingEnabled = true
}
sceneView.session.run(config, options: [])
    
let currentFrame = sceneView.session.currentFrame
let rearCameraTransform = currentFrame?.camera.transform
let rearCameraAnchors = currentFrame?.anchors
    
print(rearCameraTransform?.columns.3 as Any)
print(rearCameraAnchors as Any)

但是,当然,您可以在世界跟踪环境中控制所有ARFaceAnchors

提示:

在 ARKit 5.0 中,您可以在以下设备上使用 ARFaceTrackingConfiguration 配置:

TrueDepth sensor iOS version CPU Depth data
if YES iOS11 ....... iOS15 A11, A12, A13, A14, A15 true
if NO iOS13 ....... iOS15 A12, A13, A14, A15 false

因此,作为开发者,您需要检查当前设备是否支持面部跟踪配置:

import ARKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        if !ARFaceTrackingConfiguration.isSupported {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "unsupportedDeviceMessage")
        }
        return true
    }
}