Sam Bing
Sam Bing

Reputation: 2872

iOS Face Detection Position

I tried doing face detection in a manner of different ways, right now im experimenting with Apples Sqaure Cam translated in Swift. https://github.com/wayn/SquareCam-Swift

What i want to do is use the coordinates from the CIDetector so that i can use that position to overlay a layer over the left eye,right eye, or the mouth. But when i use the coordinates provided by the CIDetector the layer that i want to append to the face features isn't positioned correctly. My problem is specifically with this code. Since it seems to handle orientation and rotation to properly position a red box around the face.

Here's the code:

func drawFaceBoxesForFeatures(features : NSArray, clap : CGRect, orientation : UIDeviceOrientation) {



        let sublayers : NSArray = previewLayer.sublayers!
        let sublayersCount : Int = sublayers.count
        var currentSublayer : Int = 0
        //        var featuresCount : Int = features.count
        var currentFeature : Int = 0

        CATransaction.begin()
        CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)

        // hide all the face layers
        for layer in sublayers as! [CALayer] {
            if (layer.name != nil && layer.name == "FaceLayer") {
                layer.hidden = true
            }
        }

        if ( features.count == 0 || !detectFaces ) {
            CATransaction.commit()
            return
        }

        let parentFrameSize : CGSize = previewView.frame.size
        let gravity : NSString = previewLayer.videoGravity

        let previewBox : CGRect = ViewController.videoPreviewBoxForGravity(gravity, frameSize: parentFrameSize, apertureSize: clap.size)




        for ff in features as! [CIFaceFeature] {
            // set text on label
            var x : CGFloat = 0.0, y : CGFloat = 0.0
            if ff.hasLeftEyePosition {
                x = ff.leftEyePosition.x
                y = ff.leftEyePosition.y
                eyeLeftLabel.text = ff.leftEyeClosed ? "(\(x) \(y))" : "(\(x) \(y))" + "👀"


            }

            if ff.hasRightEyePosition {
                x = ff.rightEyePosition.x
                y = ff.rightEyePosition.y
                eyeRightLabel.text = ff.rightEyeClosed ? "(\(x) \(y))" : "(\(x) \(y))" + "👀"


            }

            if ff.hasMouthPosition {
                x = ff.mouthPosition.x
                y = ff.mouthPosition.y
                mouthLabel.text = ff.hasSmile ? "\(x) \(y)" + "😊" : "(\(x) \(y))"
            }

            // find the correct position for the square layer within the previewLayer
            // the feature box originates in the bottom left of the video frame.
            // (Bottom right if mirroring is turned on)
            var faceRect : CGRect = ff.bounds

            // flip preview width and height
            var temp : CGFloat = faceRect.width
            faceRect.size.width = faceRect.height
            faceRect.size.height = temp
            temp = faceRect.origin.x
            faceRect.origin.x = faceRect.origin.y
            faceRect.origin.y = temp
            // scale coordinates so they fit in the preview box, which may be scaled
            let widthScaleBy = previewBox.size.width / clap.size.height
            let heightScaleBy = previewBox.size.height / clap.size.width
            faceRect.size.width *= widthScaleBy
            faceRect.size.height *= heightScaleBy
            faceRect.origin.x *= widthScaleBy
            faceRect.origin.y *= heightScaleBy


            faceRect = CGRectOffset(faceRect, previewBox.origin.x, previewBox.origin.y)
            var featureLayer : CALayer? = nil
            // re-use an existing layer if possible
            while (featureLayer == nil) && (currentSublayer < sublayersCount) {

                let currentLayer : CALayer = sublayers.objectAtIndex(currentSublayer++) as! CALayer

                if currentLayer.name == nil {
                    continue
                }
                let name : NSString = currentLayer.name!
                if name.isEqualToString("FaceLayer") {
                    featureLayer = currentLayer;
                    currentLayer.hidden = false
                }
            }

            // create a new one if necessary
            if featureLayer == nil {
                featureLayer = CALayer()
                featureLayer?.contents = square.CGImage
                featureLayer?.name = "FaceLayer"
                previewLayer.addSublayer(featureLayer!)
            }

            featureLayer?.frame = faceRect

            currentFeature++
        }

        CATransaction.commit()
    }
`

What steps do i have to take to position the overlay layers properly over the eyes and mouth?

Upvotes: 1

Views: 1600

Answers (1)

dimohamdy
dimohamdy

Reputation: 3053

I face this problem and i solve it using change the videoGravity to AVLayerVideoGravityResize

   previewLayer?.videoGravity = AVLayerVideoGravityResize 

Upvotes: 1

Related Questions