AVFoundation 是一个能够用来使用和建立基于时间的视听媒体数据的框架。AVFoundation 的构建考虑到了目前的硬件环境和应用程序,其设计过程高度依赖多线程机制。充分利用了多核硬件的优点并大量使用block和GCD机制,将复杂的计算机进程放到了后台线程运行。会自动提供硬件加速操做,确保在大部分设备上应用程序能以最佳性能运行。算法
若是你有更好的建议或者对这篇文章有不满的地方, 请联系我, 我会进行修改, 联系我时,请备注使用AVFoundatio实现动态人脸识别(技术交流群:656315826) 最后: 祝你们学习愉快~谢谢~
1 负责把捕捉的音频视频数据输出到输出设备中。 2 一个AVCaptureSession能够有多个输入或输出。 3是链接AVCaptureInput和AVCaptureOutput的桥梁,它协调input到output之间传输数据。 4 它有startRunning和stopRunning两种方法来开启会话和结束会话。 5 每一个session称之为一个会话,也就是在应用运行过程当中若是你须要改变会话的一些配置(例如:切换摄像头),此时须要先开启配置,配置完成以后再提交配置。
输出设备数组
//建立原数据的输出对象 let metadataOutput = AVCaptureMetadataOutput() //设置代理监听输出对象输出的数据,在主线程中刷新 metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) //告诉输出对象要输出什么样的数据,识别人脸, 最多可识别10张人脸 metadataOutput.metadataObjectTypes = [.face]
切换摄像头session
@IBAction func switchCameraAction(_ sender: Any) { //执行转场动画 let anima = CATransition() anima.type = "oglFlip" anima.subtype = "fromLeft" anima.duration = 0.5 view.layer.add(anima, forKey: nil) //获取当前摄像头 guard let deviceIn = deviceInput else { return } let position: AVCaptureDevice.Position = deviceIn.device.position == .back ? .front : .back //建立新的input let deviceSession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: position) guard let newDevice = deviceSession.devices.filter({ $0.position == position }).first else { return } guard let newVideoInput = try? AVCaptureDeviceInput(device: newDevice) else { return } //移除旧输入,添加新输入 //设备加锁 session.beginConfiguration() //移除旧设备 session.removeInput(deviceIn) //添加新设备 session.addInput(newVideoInput) //设备解锁 session.commitConfiguration() //保存最新输入 deviceInput = newVideoInput
处理扫描结果多线程
实现AVCaptureMetadataOutputObjectsDelegate该协议的协议方法(只有一个方法) AVMetadataFaceObject介绍app
获取预览图层的人脸数组框架
fileprivate func transformedFaces(faceObjs: [AVMetadataObject]) -> [AVMetadataObject] { var faceArr = [AVMetadataObject]() for face in faceObjs { //将扫描的人脸对象转成在预览图层的人脸对象(主要是坐标的转换) if let transFace = previewLayer.transformedMetadataObject(for: face){ faceArr.append(transFace) } } return faceArr }
根据人脸位置添加红框ide
设置红框的frame函数
faceLayer?.frame = face.bounds
根据偏转角和倾斜角的角度获取CATransform3D性能
fileprivate func transformDegress(yawAngle: CGFloat) -> CATransform3D { let yaw = degreesToRadians(degress: yawAngle) //围绕Y轴旋转 let yawTran = CATransform3DMakeRotation(yaw, 0, -1, 0) //红框旋转问题 return CATransform3DConcat(yawTran, CATransform3DIdentity) } //处理偏转角问题 fileprivate func transformDegress(rollAngle: CGFloat) -> CATransform3D { let roll = degreesToRadians(degress: rollAngle) //围绕Z轴旋转 return CATransform3DMakeRotation(roll, 0, 0, 1) } //角度转换 fileprivate func degreesToRadians(degress: CGFloat) -> CGFloat{ return degress * CGFloat(Double.pi) / 180 }
根据有无偏转角和倾斜角旋转红框学习
//设置偏转角(左右摇头) if face.hasYawAngle{ let tranform3D = transformDegress(yawAngle: face.yawAngle) //矩阵处理 faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D) } //设置倾斜角,侧倾角(左右歪头) if face.hasRollAngle{ let tranform3D = transformDegress(rollAngle: face.rollAngle) //矩阵处理 faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D) }
至此, 动态的人脸识别就完成了, 会在人脸位置增长红框显示, 而且红框会根据人脸的位置动态的, 实时的调整
下面就快拿起你的相机测试吧
想要获取案例源码能够加我技术交流群:656315826 最近我在研究这一块,若是你有更好的建议或者对这篇文章有不满的地方, 请联系我, 我会进行修改,共同窗习进步。
祝你们学习愉快