难以从 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.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!
您正在使用 ARFaceTrackingConfiguration
,对吗?在那种情况下,featurePoint
命中测试类型将无济于事,因为特征点是世界跟踪的一部分,而不是面部跟踪……事实上,几乎所有 ARKit 命中测试机制特定于世界跟踪,对面部跟踪没有用。
您可以做的是利用面部网格 (ARFaceGeometry
) 和面部姿势跟踪 (ARFaceAnchor
) 从 2D 图像点到 3D 世界-space(或相机-space)点。为此,您至少可以走几条路:
如果您已经在使用 SceneKit,则可以使用 SceneKit 的命中测试而不是 ARKit 的。 (也就是说,您是针对在 SceneKit 中建模的 "virtual" 几何体进行命中测试,而不是针对由 ARKit 建模的真实世界环境的稀疏估计。在这种情况下,面部网格的 "virtual" 几何体通过 ARKit 进入 SceneKit。)也就是说,你想要 ARSCNView.hitTest(_:options:)
(继承自 SCNSceneRenderer
),而不是 hitTest(_:types:)
。当然,这意味着您需要使用 ARSCNFaceGeometry
来可视化场景中的面部网格,并需要使用 ARSCNView
的 node/anchor 映射来跟踪面部姿势(尽管如果你想让视频图像显示出来,你可以使网格透明)——否则 SceneKit 命中测试将找不到任何 SceneKit 几何体。
如果您没有使用 SceneKit,或者由于某种原因无法将面部网格放入您的场景中,您拥有重建针对面部网格的命中测试所需的所有信息。 ARCamera
具有视图和投影矩阵,可以告诉您 2D 屏幕投影与 3D 世界的关系 space,ARFaceAnchor
告诉您面部在世界中的位置 space,以及 ARFaceGeometry
告诉你每个点在脸上的位置——所以它只是一个 bunch of math 从屏幕点到面部网格点,反之亦然。
我 运行 在 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!
您正在使用 ARFaceTrackingConfiguration
,对吗?在那种情况下,featurePoint
命中测试类型将无济于事,因为特征点是世界跟踪的一部分,而不是面部跟踪……事实上,几乎所有 ARKit 命中测试机制特定于世界跟踪,对面部跟踪没有用。
您可以做的是利用面部网格 (ARFaceGeometry
) 和面部姿势跟踪 (ARFaceAnchor
) 从 2D 图像点到 3D 世界-space(或相机-space)点。为此,您至少可以走几条路:
如果您已经在使用 SceneKit,则可以使用 SceneKit 的命中测试而不是 ARKit 的。 (也就是说,您是针对在 SceneKit 中建模的 "virtual" 几何体进行命中测试,而不是针对由 ARKit 建模的真实世界环境的稀疏估计。在这种情况下,面部网格的 "virtual" 几何体通过 ARKit 进入 SceneKit。)也就是说,你想要
ARSCNView.hitTest(_:options:)
(继承自SCNSceneRenderer
),而不是hitTest(_:types:)
。当然,这意味着您需要使用ARSCNFaceGeometry
来可视化场景中的面部网格,并需要使用ARSCNView
的 node/anchor 映射来跟踪面部姿势(尽管如果你想让视频图像显示出来,你可以使网格透明)——否则 SceneKit 命中测试将找不到任何 SceneKit 几何体。如果您没有使用 SceneKit,或者由于某种原因无法将面部网格放入您的场景中,您拥有重建针对面部网格的命中测试所需的所有信息。
ARCamera
具有视图和投影矩阵,可以告诉您 2D 屏幕投影与 3D 世界的关系 space,ARFaceAnchor
告诉您面部在世界中的位置 space,以及ARFaceGeometry
告诉你每个点在脸上的位置——所以它只是一个 bunch of math 从屏幕点到面部网格点,反之亦然。