难以从 iPhone X 上的 2D 区域获取面部特征点的深度(SceneKit/ARKit 应用程序)

Difficulty getting depth of face landmark points from 2D regions on iPhone X (SceneKit/ARKit app)

我 运行 在 iPhone X 上使用前置摄像头进行人脸标志检测,我正在努力获取人脸标志的 3D 点(VNFaceLandmarkRegion2D 给出图像坐标 X、Y只要)。

我一直在尝试使用 ARSCNView.hitTestARFrame.hitTest,但到目前为止都没有成功。我认为我的错误可能在于将初始地标点转换为正确的坐标系。我已经尝试了很多排列组合,但目前根据我的研究,这是我想出的:

let point = CGPoint(x: landmarkPt.x * faceBounds.width + faceBounds.origin.x, y: (1.0 - landmarkPt.y) * faceBounds.height + faceBounds.origin.y)
let screenPoint = CGPoint(point.x * view.bounds.width, point.y * view.bounds.height)
frame.hitTest(screenPoint, types: ARHitTestResult.ResultType.featurePoint)

我也试过

let newPoint = CGPoint(x: point.x, y: 1.0 - point.y) 

转换后,但似乎没有任何效果。我的 frame.hitTest 结果总是空的。我在转换中遗漏了什么吗?

前置摄像头是不是又增加了一个层次? (我还尝试在某一点反转初始 X 值,以防坐标系被镜像)。在我看来,初始地标 normalizedPoints 有时为负,有时也大于 1.0,这对我来说没有任何意义。如果这很重要,我正在使用 ARSession.currentFrame?.capturedImage 捕捉前置摄像头的画面。

非常非常感谢任何帮助,非常感谢!

-- 已解决 --

对于有类似问题的任何人: 我终于得到了命中测试结果!

for point in observation.landmarks?.allPoints?.pointsInImage(imageSize: sceneView.bounds.size) {
    let result = ARSCNView.hitTest(point, options: [ARSCNHitTestOption.rootNode: faceNode)
}

我使用面部几何体作为附加到面部节点的遮挡节点。

谢谢 Rickster!

您正在使用 ARFaceTrackingConfiguration,对吗?在那种情况下,featurePoint 命中测试类型将无济于事,因为特征点是世界跟踪的一部分,而不是面部跟踪……事实上,几乎所有 ARKit 命中测试机制特定于世界跟踪,对面部跟踪没有用。

您可以做的是利用面部网格 (ARFaceGeometry) 和面部姿势跟踪 (ARFaceAnchor) 从 2D 图像点到 3D 世界-space(或相机-space)点。为此,您至少可以走几条路:

  1. 如果您已经在使用 SceneKit,则可以使用 SceneKit 的命中测试而不是 ARKit 的。 (也就是说,您是针对在 SceneKit 中建模的 "virtual" 几何体进行命中测试,而不是针对由 ARKit 建模的真实世界环境的稀疏估计。在这种情况下,面部网格的 "virtual" 几何体通过 ARKit 进入 SceneKit。)也就是说,你想要 ARSCNView.hitTest(_:options:)(继承自 SCNSceneRenderer),而不是 hitTest(_:types:)。当然,这意味着您需要使用 ARSCNFaceGeometry 来可视化场景中的面部网格,并需要使用 ARSCNView 的 node/anchor 映射来跟踪面部姿势(尽管如果你想让视频图像显示出来,你可以使网格透明)——否则 SceneKit 命中测试将找不到任何 SceneKit 几何体。

  2. 如果您没有使用 SceneKit,或者由于某种原因无法将面部网格放入您的场景中,您拥有重建针对面部网格的命中测试所需的所有信息。 ARCamera 具有视图和投影矩阵,可以告诉您 2D 屏幕投影与 3D 世界的关系 space,ARFaceAnchor 告诉您面部在世界中的位置 space,以及 ARFaceGeometry 告诉你每个点在脸上的位置——所以它只是一个 bunch of math 从屏幕点到面部网格点,反之亦然。