###简介 AVFoundation 是一个能够用来使用和建立基于时间的视听媒体数据的框架。AVFoundation 的构建考虑到了目前的硬件环境和应用程序,其设计过程高度依赖多线程机制。充分利用了多核硬件的优点并大量使用block和GCD机制,将复杂的计算机进程放到了后台线程运行。会自动提供硬件加速操做,确保在大部分设备上应用程序能以最佳性能运行。算法
(技术交流群:923910776)数组
###介绍一些人脸识别的方式bash
###对关键类的简单介绍session
1 负责把捕捉的音频视频数据输出到输出设备中。
2 一个AVCaptureSession能够有多个输入或输出。
3是链接AVCaptureInput和AVCaptureOutput的桥梁,它协调input到output之间传输数据。
4 它有startRunning和stopRunning两种方法来开启会话和结束会话。
5 每一个session称之为一个会话,也就是在应用运行过程当中若是你须要改变会话的一些配置(例如:切换摄像头),此时须要先开启配置,配置完成以后再提交配置。
复制代码
###添加扫描设备多线程
输出设备app
//建立原数据的输出对象
let metadataOutput = AVCaptureMetadataOutput()
//设置代理监听输出对象输出的数据,在主线程中刷新
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
//告诉输出对象要输出什么样的数据,识别人脸, 最多可识别10张人脸
metadataOutput.metadataObjectTypes = [.face]
复制代码
切换摄像头框架
@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
复制代码
处理扫描结果ide
实现AVCaptureMetadataOutputObjectsDelegate该协议的协议方法(只有一个方法) AVMetadataFaceObject介绍函数
获取预览图层的人脸数组性能
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
}
复制代码
根据人脸位置添加红框
设置红框的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)
}
复制代码
至此, 动态的人脸识别就完成了, 会在人脸位置增长红框显示, 而且红框会根据人脸的位置动态的, 实时的调整
下面就快拿起你的相机测试吧