【问题标题】:Distance between face and camera using ARKit使用 ARKit 的面部和相机之间的距离
【发布时间】:2018-12-06 19:10:22
【问题描述】:

你在哪里可以使用 ARKit 获取相机和人脸之间的距离?

【问题讨论】:

    标签: ios swift arkit


    【解决方案1】:

    我认为这可以通过使用 ARFaceAnchor.leftEyeTransformARFaceAnchor.rightEyeTransform 属性来实现。

    一旦有了这些,您就可以使用眼睛的worldPosition 并减去相机的位置来获得眼睛到相机的大致距离,例如SCNVector3Zero.

    下面是一个非常粗略的例子,所有代码都被注释了,所以应该很容易理解:

    //------------------------------
    // MARK: - SCNVector3 Extensions
    //------------------------------
    
    extension SCNVector3{
    
        ///Get The Length Of Our Vector
        func length() -> Float { return sqrtf(x * x + y * y + z * z) }
    
        ///Allow Us To Subtract Two SCNVector3's
        static func - (l: SCNVector3, r: SCNVector3) -> SCNVector3 { return SCNVector3Make(l.x - r.x, l.y - r.y, l.z - r.z) }
    }
    
    //--------------------------
    // MARK: - ARSCNViewDelegate
    //--------------------------
    
    extension ViewController: ARSCNViewDelegate{
    
        func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    
            //1. Setup The FaceNode & Add The Eyes
            faceNode = node
            faceNode.addChildNode(leftEye)
            faceNode.addChildNode(rightEye)
            faceNode.transform = node.transform
    
            //2. Get The Distance Of The Eyes From The Camera
            trackDistance()
        }
    
        func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    
            faceNode.transform = node.transform
    
            //2. Check We Have A Valid ARFaceAnchor
            guard let faceAnchor = anchor as? ARFaceAnchor else { return }
    
            //3. Update The Transform Of The Left & Right Eyes From The Anchor Transform
            leftEye.simdTransform = faceAnchor.leftEyeTransform
            rightEye.simdTransform = faceAnchor.rightEyeTransform
    
            //4. Get The Distance Of The Eyes From The Camera
            trackDistance()
        }
    
    
        /// Tracks The Distance Of The Eyes From The Camera
        func trackDistance(){
    
            DispatchQueue.main.async {
    
                //4. Get The Distance Of The Eyes From The Camera
                let leftEyeDistanceFromCamera = self.leftEye.worldPosition - SCNVector3Zero
                let rightEyeDistanceFromCamera = self.rightEye.worldPosition - SCNVector3Zero
    
                //5. Calculate The Average Distance Of The Eyes To The Camera
                let averageDistance = (leftEyeDistanceFromCamera.length() + rightEyeDistanceFromCamera.length()) / 2
                let averageDistanceCM = (Int(round(averageDistance * 100)))
                print("Approximate Distance Of Face From Camera = \(averageDistanceCM)")
            }
        }
    }
    
    class ViewController: UIViewController{
    
        @IBOutlet var sceneView: ARSCNView!
    
        var faceNode = SCNNode()
        var leftEye = SCNNode()
        var rightEye = SCNNode()
    
        //-----------------------
        // MARK: - View LifeCycle
        //-----------------------
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //1. Set Up Face Tracking
            guard ARFaceTrackingConfiguration.isSupported else { return }
            let configuration = ARFaceTrackingConfiguration()
            configuration.isLightEstimationEnabled = true
            sceneView.delegate = self
            sceneView.showsStatistics = true
            sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    
            //2. Setup The Eye Nodes
            setupEyeNode()
        }
    
        override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) }
    
        //-----------------------
        // MARK: - Eye Node Setup
        //-----------------------
    
        /// Creates To SCNSpheres To Loosely Represent The Eyes
        func setupEyeNode(){
    
            //1. Create A Node To Represent The Eye
            let eyeGeometry = SCNSphere(radius: 0.005)
            eyeGeometry.materials.first?.diffuse.contents = UIColor.cyan
            eyeGeometry.materials.first?.transparency = 1
    
            //2. Create A Holder Node & Rotate It So The Gemoetry Points Towards The Device
            let node = SCNNode()
            node.geometry = eyeGeometry
            node.eulerAngles.x = -.pi / 2
            node.position.z = 0.1
    
            //3. Create The Left & Right Eyes
            leftEye = node.clone()
            rightEye = node.clone()
        }
    
    }
    

    希望对你有帮助...

    【讨论】:

    • @ankit.tlp,请接受这个答案,它工作得很好!谢谢@BlackMirrorz!
    • @BlackMirrorz 真的很有用,这个length() -> Float 扩展!当距离超过 0.9 米(35.4 英寸)时,我无法跟踪面部距离,ARKit 回调没有触发。有什么技巧可以在一米以上的范围内跟踪人脸吗?
    • 这是完美的答案。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    相关资源
    最近更新 更多