I'm playing around with Apples CIDetector to detect a face from live video using the front camera of the phone. I've been following this article and have nearly got it working. The problem I'm having is a new red box is being created on every frame rather the same one being reused.
The tutorial I'm following is meant to have code to stop that from happening but it doesn't seem to be working. I'm still very new to Swift and am struggling to work it out.
Here's the code I'm using:
func drawFaceMasksFor(features: [CIFaceFeature], bufferFrame: CGRect) {
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
//Hide all current masks
view.layer.sublayers?.filter({ $0.name == "MaskFace" }).forEach { $0.isHidden = true }
//Do nothing if no face is dected
guard !features.isEmpty else {
CATransaction.commit()
return
}
//The problem is we detect the faces on video image size
//but when we show on the screen which might smaller or bigger than your video size
//so we need to re-calculate the faces bounds to fit to your screen
let xScale = view.frame.width / bufferFrame.width
let yScale = view.frame.height / bufferFrame.height
let transform = CGAffineTransform(rotationAngle: .pi).translatedBy(x: -bufferFrame.width,
y: -bufferFrame.height)
for feature in features {
var faceRect = feature.bounds.applying(transform)
faceRect = CGRect(x: faceRect.minX * xScale,
y: faceRect.minY * yScale,
width: faceRect.width * xScale,
height: faceRect.height * yScale)
//Reuse the face's layer
var faceLayer = view.layer.sublayers?
.filter { $0.name == "MaskFace" && $0.isHidden == true }
.first
if faceLayer == nil {
// prepare layer
faceLayer = CALayer()
faceLayer?.backgroundColor = UIColor.clear.cgColor
faceLayer?.borderColor = UIColor.red.cgColor
faceLayer?.borderWidth = 3.0
faceLayer?.frame = faceRect
faceLayer?.masksToBounds = true
faceLayer?.contentsGravity = kCAGravityResizeAspectFill
view.layer.addSublayer(faceLayer!)
} else {
faceLayer?.frame = faceRect
faceLayer?.position = faceRect.origin
faceLayer?.isHidden = false
}
//You can add some masks for your left eye, right eye, mouth
}
CATransaction.commit()
}