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

我正在使用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) } 

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

谢谢里克斯特!

你正在使用ARFaceTrackingConfiguration ,对吗? 在这种情况下, featurePoint命中测试类型对你没有帮助,因为特征点是世界跟踪的一部分,而不是面部跟踪…事实上,几乎所有的ARKit命中测试机器都是特定于世界跟踪的,并没有用面对跟踪。

你可以做的是利用面部网格( ARFaceGeometry )和面部姿势跟踪( ARFaceAnchor )来从2D图像点到3D世界空间(或相机空间)点。 至少有几条路可以让你失望:

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

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