Reputation: 2872
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
Reputation: 3053
I face this problem and i solve it using change the videoGravity to AVLayerVideoGravityResize
previewLayer?.videoGravity = AVLayerVideoGravityResize
Upvotes: 1