我正在尝试检测iOS相机应用中的脸部,但它doesn't work properly,而works properly in Camera.app。请注意:
为什么会这样?
我的代码如下。你看错了吗?
首先,我按如下方式创建视频输出:
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.videoSettings =
[kCVPixelBufferPixelFormatTypeKey as AnyHashable:
Int(kCMPixelFormat_32BGRA)]
session.addOutput(videoOutput)
videoOutput.setSampleBufferDelegate(faceDetector, queue: faceDetectionQueue)
这是代表:
class FaceDetector: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ captureOutput: AVCaptureOutput!,
didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
from connection: AVCaptureConnection!) {
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
let features = FaceDetector.ciDetector.features(
in: CIImage(cvPixelBuffer: imageBuffer))
let faces = features.map { $0.bounds }
let imageSize = CVImageBufferGetDisplaySize(imageBuffer)
let faceBounds = faces.map { (face: CIFeature) -> CGRect in
var ciBounds = face.bounds
ciBounds = ciBounds.applying(
CGAffineTransform(scaleX: 1/imageSize.width, y: -1/imageSize.height))
CGRect(x: 0, y: 0, width: 1, height: -1).verifyContains(ciBounds)
let bounds = ciBounds.applying(CGAffineTransform(translationX: 0, y: 1.0))
CGRect(x: 0, y: 0, width: 1, height: 1).verifyContains(bounds)
return bounds
}
DispatchQueue.main.sync {
facesUpdated(faceBounds, imageSize)
}
}
private static let ciDetector = CIDetector(ofType: CIDetectorTypeFace,
context: nil,
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])!
}
facesUpdated()回调如下:
class PreviewView: UIView {
private var faceRects = [UIView]()
private static func makeFaceRect() -> UIView {
let r = UIView()
r.layer.borderWidth = FocusRect.borderWidth
r.layer.borderColor = FocusRect.color.cgColor
faceRects.append(r)
addSubview(r)
return r
}
private func removeAllFaceRects() {
for faceRect in faceRects {
verify(faceRect.superview == self)
faceRect.removeFromSuperview()
}
faceRects.removeAll()
}
private func facesUpdated(_ faces: [CGRect], _ imageSize: CGSize) {
removeAllFaceRects()
let faceFrames = faces.map { (original: CGRect) -> CGRect in
let face = original.applying(CGAffineTransform(scaleX: bounds.width, y: bounds.height))
verify(self.bounds.contains(face))
return face
}
for faceFrame in faceFrames {
let faceRect = PreviewView.makeFaceRect()
faceRect.frame = faceFrame
}
}
}
我也尝试了以下内容,但他们没有帮助: