swift ARRaycast查询和前置摄像头(ARFaceTrackingConfiguration)

c9qzyr3d  于 12个月前  发布在  Swift
关注(0)|答案(1)|浏览(138)

我已经搜索了所有的文档,可能只是错过了一些非常重要的东西。光线投射是否可以在前置True Depth摄像头上使用,比如iPad Pro上?
我目前正在做一个应用程序,我在ARFaceTrackingConfiguration中,从屏幕中心进行简单的光线投射没有产生结果。
使用后置摄像头的世界配置中的相同代码正在产生结果。此代码直接来自文档。

let raycastQuery: ARRaycastQuery? = sceneView.raycastQuery(
                                                      from: sceneView.center,
                                                  allowing: .estimatedPlane,
                                                 alignment: .any)

let rayresults: [ARRaycastResult] = sceneView.session.raycast(raycastQuery!)
print(rayresults)

字符串
我的理解是,考虑到背景模糊的面部跟踪深度图的例子,前置摄像头将具有与后置摄像头基本相同的深度数据,只是可用的总深度距离较少。
由于这段代码返回了后置摄像头的结果集,但没有返回前置摄像头的结果,我想知道这是不是因为光线的方向?对于前置摄像头,如果支持rayCast,也许它需要光线在负z方向投射?但我还没有成功。
该项目的目标是能够在3D空间中获得2点之间的距离,但使用前置摄像头而不是后置摄像头。
谢谢你让我明白了我很感激

dced5bon

dced5bon1#

ARFaceTrackingConfig点击测试

很明显,基于World Tracking配置用于检测平面的ARKit光线投射方法不适用于Face Tracking场景。在您的情况下,您需要使用SceneKit的hit-testing。对于hit-testing,您将无法使用estimatedPlane,你需要一个canonical face mask。当使用前置摄像头时,你对XZ坐标的理解是完全正确的-XZ平面是镜像的。另外值得注意的是,相机的IR TrueDepth传感器在10到100 cm的距离下“工作”。ARFaceAnchor仅在此范围内生成。
在iPad Pro上的Swift Playgrounds应用中运行此代码。

import ARKit
import SceneKit
import PlaygroundSupport

class ViewController : UIViewController {
    var sceneView = ARSCNView(frame: .zero)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = self.sceneView
        sceneView.delegate = self
        sceneView.scene = SCNScene()
        
        let config = ARFaceTrackingConfiguration()
        config.maximumNumberOfTrackedFaces = 1
        sceneView.session.run(config)
    }
}
extension ViewController {       
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let location: CGPoint? = touches.first?.location(in: sceneView)
                                            
        var hitTestOptions = [SCNHitTestOption: Any]()
        hitTestOptions[.boundingBoxOnly] = true
                                            
        let hitTestResults: [SCNHitTestResult] = sceneView.hitTest(location!, 
                                                   options: hitTestOptions)
                    
        guard let hit = hitTestResults.first else { return }
                                        
        let sphere = SCNNode(geometry: SCNSphere(radius: 0.005))
        sphere.simdPosition = hit.simdWorldCoordinates
        sceneView.scene.rootNode.addChildNode(sphere)            
    }
}
extension ViewController : ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        let faceGeo = ARSCNFaceGeometry(device: sceneView.device!)
        let node = SCNNode(geometry: faceGeo)
        node.geometry?.firstMaterial?.lightingModel = .physicallyBased
        node.geometry?.firstMaterial?.diffuse.contents = UIColor.green
        return node
    }
    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode,
                                                    for anchor: ARAnchor) {    
        if let faceAnchor = anchor as? ARFaceAnchor,
           let faceGeo = node.geometry as? ARSCNFaceGeometry {
            faceGeo.update(from: faceAnchor.geometry)
        }
    }
}

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = ViewController()

相关问题