首页 文章

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

提问于
浏览
2

我正在使用 iPhone X 上的 front-facing 相机进行面部地标检测,并且我非常努力地获得 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结果总是空的。我在转换中遗漏了什么吗?

front-facing 相机是否为此添加了另一个级别? (我还尝试在一个点反转初始 X 值,以防镜像坐标系)。在我看来,最初的里程碑normalizedPoints有时是负面的,有时甚至大于 1.0,这对我没有任何意义。我正在使用ARSession.currentFrame?.capturedImage来捕捉 front-facing 相机的帧,如果这很重要的话。

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

  • 解决了 -

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

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

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

谢谢里克斯特!

1 回答

  • 2

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

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

    • 如果你已经在使用 SceneKit,你可以使用 SceneKit 的命中测试代替 ARKit。 (也就是说,你正在针对在 SceneKit 中建模的“虚拟”几何体进行测试,而不是针对由 ARKit 建模的 real-world 环境的稀疏估计.在这种情况下,面部网格的“虚拟”几何体通过 ARKit.)进入 SceneKit。是的,你想要ARSCNView.hitTest(_:options:)(继承自SCNSceneRenderer),而不是hitTest(_:types:)。当然,这意味着你需要使用ARSCNFaceGeometry来可视化场景中的面部网格,并使用ARSCNView的 node/anchor 贴图来跟踪面部姿势(虽然如果你想要显示视频图像,你可以使网格透明) - 否则 SceneKit 命中测试将不会找到任何 SceneKit 几何。

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

相关问题