使用ARKit的面部和相机之间的距离

时间:2018-06-27 19:49:38

标签: ios swift arkit

您是否可以使用ARKit在相机和人脸之间找到距离?

1 个答案:

答案 0 :(得分:4)

我认为可以通过使用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()
    }

}

希望有帮助...