我正在使用iPhone X上的前置摄像头进行脸部地标检测,并且我非常努力地获得3D点面部标记(VNFaceLandmarkRegion2D仅提供图像坐标X,Y)。
我一直在尝试使用ARSCNView.hitTest
或ARFrame.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!
答案 0 :(得分:2)
您正在使用ARFaceTrackingConfiguration
,对吗?在这种情况下,featurePoint
点击测试类型对您没有帮助,因为要素点是世界跟踪的一部分,而不是面部跟踪...实际上,几乎所有的 ARKit 命中测试机器特定于世界跟踪,对面部跟踪无用。
您可以做的是使用面部网格(ARFaceGeometry
)和面部姿势跟踪(ARFaceAnchor
)来从2D图像点到3D世界空间(或者相机空间)点。至少有几条路可以为此做准备:
如果你已经在使用SceneKit,你可以使用 SceneKit 的命中测试代替ARKit。 (也就是说,你是针对在SceneKit中建模的“虚拟”几何体进行测试,而不是针对由ARKit建模的真实世界环境的稀疏估计。在这种情况下,面部网格的“虚拟”几何体通过SceneKit进入ARKit。)也就是说,您想要ARSCNView.hitTest(_:options:)
(继承自SCNSceneRenderer
),而不是hitTest(_:types:)
。当然,这意味着您需要使用ARSCNFaceGeometry
来显示场景中的面部网格,并使用ARSCNView
的节点/锚点映射来跟踪面部姿势(尽管如果您需要)要显示的视频图像,您可以使网格透明) - 否则SceneKit命中测试将不会找到任何SceneKit几何体。
如果您没有使用SceneKit,或者出于某种原因无法将脸部网格物体放入场景中,您将获得重建针对脸部网格物体的命中测试所需的所有信息。 ARCamera
有视图和投影矩阵,告诉您2D屏幕投影与3D世界空间的关系,ARFaceAnchor
告诉您脸部在世界空间中的位置,ARFaceGeometry
告诉您每个点在脸上 - 所以它只是bunch of math从屏幕点到脸部网格点,反之亦然。