iOS黑科技之(AVFoundation)动态人脸识别(二)

上一篇介绍了Core Image实现的静态人脸识别, 这里介绍AVFoundation的强大功能之一的动态人脸识别

一. 首先介绍一些人脸识别的方式

1. CoreImage静态人脸识别, 可识别照片, 图像等

  • 详情可查看上一篇博客介绍

2. Face++

  • 是北京旷视科技有限公司旗下的新型视觉服务平台, 旨在提供简单易用,功能强大,平台通用的视觉服务
  • Face++是新一代云端视觉服务平台,提供一整套世界领先的人脸检测,人脸识别,面部分析的视觉技术服务
  • Face++百度百科介绍
  • Face++官网

3. OpenCV

  • 由一系列 C 函数和少量 C++ 类构成, 实现了图像处理和计算机视觉方面的很多通用算法, 其他的具体的不是很了解
  • 这是百度百科的内容

4. Vision

  • Vision 是 Apple 在 WWDC 2017 伴随iOS 11推出的基于CoreML的图像识别框架
  • 根据Vision官方文档看,Vision 本身就有Face Detection and Recognition(人脸检测识别)、Machine Learning Image Analysis(机器学习图片分析)、Barcode Detection(条形码检测)、Text Detection(文本检测)。。。。。等等这些功能
  • 感兴趣的同学可以查看相关文档学习一下, 这里小编就不过多作介绍了

5. AVFoundation

  • 可以用来使用和创建基于时间的视听媒体的框架
  • 这里我们使用的人脸识别方式也是使用AVFoundation框架

二. 对关键类的简单介绍

1. AVCaptureDevice:代表硬件设备

  • 我们可以从这个类中获取手机硬件的照相机、声音传感器等。
  • 当我们在应用程序中需要改变一些硬件设备的属性(例如:切换摄像头、闪光模式改变、相机聚焦改变)的时候必须要先为设备加锁,修改完成后解锁。
  • 示例: 切换摄像头
//4. 移除旧输入,添加新输入
//4.1 设备加锁
session.beginConfiguration()
//4.2. 移除旧设备
session.removeInput(deviceIn)
//4.3 添加新设备
session.addInput(newVideoInput)
//4.4 设备解锁
session.commitConfiguration()

2. AVCaptureDeviceInput:设备输入数据管理对象

  • 可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,
  • 该对象将会被添加到AVCaptureSession中管理,代表输入设备,它配置抽象硬件设备的ports。通常的输入设备有(麦克风,相机等)

3. AVCaptureOutput: 代表输出数据

  • 输出的可以是图片(AVCaptureStillImageOutput)或者视频(AVCaptureMovieFileOutput

4. AVCaptureSession: 媒体(音、视频)捕捉会话

  • 负责把捕捉的音频视频数据输出到输出设备中。
  • 一个AVCaptureSession可以有多个输入或输出。
  • 是连接AVCaptureInputAVCaptureOutput的桥梁,它协调input到output之间传输数据。
  • 它有startRunning和stopRunning两种方法来开启会话和结束会话。
  • 每个session称之为一个会话,也就是在应用运行过程中如果你需要改变会话的一些配置(例如:切换摄像头),此时需要先开启配置,配置完成之后再提交配置。

5. AVCaptureVideoPreviewLayer: 图片预览层

  • 我们的照片以及视频是如何显示在手机上的呢?那就是通过把这个对象添加到UIViewlayer上的

好了, 上面吧啦吧啦的说了那么多废话, 那么我们的人脸识别究竟是怎样实现的呢? 下面干货来了

三. 添加扫描设备

  • 获取设备(摄像头)
  • 创建输入设备
  • 创建扫描输出
  • 创建捕捉回话

1. 输出设备

  • 这里使用AVCaptureMetadataOutput, 可以扫描人脸, 二维码, 条形码等信息
  • 必须设置代理, 否则获取不到扫描结果
  • 需要设置要输出什么样的数据: face(人脸), qr(二维码)等等
//3.创建原数据的输出对象
let metadataOutput = AVCaptureMetadataOutput()//4.设置代理监听输出对象输出的数据,在主线程中刷新
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)//7.告诉输出对象要输出什么样的数据,识别人脸, 最多可识别10张人脸
metadataOutput.metadataObjectTypes = [.face]

主要代码如下:

fileprivate func addScaningVideo(){//1.获取输入设备(摄像头)guard let device = AVCaptureDevice.default(for: .video) else { return }//2.根据输入设备创建输入对象guard let deviceIn = try? AVCaptureDeviceInput(device: device) else { return }deviceInput = deviceIn//3.创建原数据的输出对象let metadataOutput = AVCaptureMetadataOutput()//4.设置代理监听输出对象输出的数据,在主线程中刷新metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)//4.2 设置输出代理faceDelegate = previewView//5.设置输出质量(高像素输出)session.sessionPreset = .high//6.添加输入和输出到会话if session.canAddInput(deviceInput!) {session.addInput(deviceInput!)}if session.canAddOutput(metadataOutput) {session.addOutput(metadataOutput)}//7.告诉输出对象要输出什么样的数据,识别人脸, 最多可识别10张人脸metadataOutput.metadataObjectTypes = [.face]//8.创建预览图层previewLayer = AVCaptureVideoPreviewLayer(session: session)previewLayer.videoGravity = .resizeAspectFillpreviewLayer.frame = view.boundspreviewView.layer.insertSublayer(previewLayer, at: 0)//9.设置有效扫描区域(默认整个屏幕区域)(每个取值0~1, 以屏幕右上角为坐标原点)metadataOutput.rectOfInterest = previewView.bounds//10. 开始扫描if !session.isRunning {DispatchQueue.global().async {self.session.startRunning()}}
}

2. 切换摄像头

  • 获取当前摄像头方向
  • 创建新的输入input
  • 移除旧输入capture, 添加新的输入capture
  • 具体代码如下:
@IBAction func switchCameraAction(_ sender: Any) {//1. 执行转场动画let anima = CATransition()anima.type = "oglFlip"anima.subtype = "fromLeft"anima.duration = 0.5view.layer.add(anima, forKey: nil)//2. 获取当前摄像头guard let deviceIn = deviceInput else { return }let position: AVCaptureDevice.Position = deviceIn.device.position == .back ? .front : .back//3. 创建新的inputlet 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 }//4. 移除旧输入,添加新输入//4.1 设备加锁session.beginConfiguration()//4.2. 移除旧设备session.removeInput(deviceIn)//4.3 添加新设备session.addInput(newVideoInput)//4.4 设备解锁session.commitConfiguration()//5. 保存最新输入deviceInput = newVideoInput
}

3. 处理扫描结果

实现AVCaptureMetadataOutputObjectsDelegate该协议的协议方法(只有一个方法)

//`metadataObjects`就是返回的扫描结果
optional public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

4. AVMetadataFaceObject介绍

  • faceID: 人脸的唯一标识

    • 扫描出来的每一个人, 有不同的faceID
    • 同一个人, 不同的状态下(摇头, 歪头, 抬头等), 都会有不同faceID
  • hasRollAngle: 是否有倾斜角,侧倾角(左右歪头)(BOOL类型)
  • rollAngle: 倾斜角,侧倾角的角度(CGFloat类型)
  • hasYawAngle: 是否有偏转角(左右摇头)
  • yawAngle: 偏转角角度

5. 处理扫描结果

5.1 获取预览图层的人脸数组

  • 遍历扫描的人脸数组, 转换成在预览图层的人脸数组
  • 主要是人脸在图层的左边的转换
  • 返回转换后的新的数组
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
}

5.2 根据人脸位置添加红框

  • 设置红框的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}
  • 根据有无偏转角和倾斜角旋转红框
//3.4 设置偏转角(左右摇头)
if face.hasYawAngle{let tranform3D = transformDegress(yawAngle: face.yawAngle)//矩阵处理faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D)
}//3.5 设置倾斜角,侧倾角(左右歪头)
if face.hasRollAngle{let tranform3D = transformDegress(rollAngle: face.rollAngle)//矩阵处理faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D)
}
  • 至此, 动态的人脸识别就完成了, 会在人脸位置增加红框显示, 并且红框会根据人脸的位置动态的, 实时的调整
  • 下面就快拿起你的相机测试吧

GitHub–Demo地址

  • 注意:

    • 这里只是列出了主要的核心代码,具体的代码逻辑请参考demo
    • 文中相关介绍有的地方如果有不是很详细或者有更好建议的,欢迎联系小编

iOS黑科技之(AVFoundation)动态人脸识别(二)相关推荐

  1. iOS黑科技之(CoreImage)静态人脸识别(一)

    iOS黑科技之(CoreImage)静态人脸识别(一) 人脸识别原理简介:每一张图片都是由每一个像素点组成,而每一个像素点中又有对应的颜色值(如RGB),人的面部特征中,不同的五官,颜色值肯定存在差异 ...

  2. AVFoundation实现动态人脸识别

    2019独角兽企业重金招聘Python工程师标准>>> 简介 AVFoundation 是一个可以用来使用和创建基于时间的视听媒体数据的框架.AVFoundation 的构建考虑到了 ...

  3. 深入动态人脸识别小场景应用,2019年或将迎来爆发期

    人脸识别已经成为人工智能技术的落地风口之一,随着人工智能和深度学习技术的逐渐成熟,人脸识别的商业化落地开始全面加速,智慧学校.工地实名制.会议签到.门禁考勤.访客预约等等,越来越多的小场景应用被解锁. ...

  4. 人脸识别(3)---静态人脸识别和动态人脸识别的区别

    静态人脸识别和动态人脸识别的区别 人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术.作为一种新型而且发展较快的技术,很多人对这门技术并没有清晰的理解和认识.比如说,人脸识别有哪些种类,人 ...

  5. 动态人脸识别系统服务器,动态人脸识别监控管理平台的设计与实现

    摘要: 动态人脸视频监控是计算机视觉领域一个新兴的应用方向和备受关注的前沿课题,它结合了计算机科学,机器视觉,图像处理,模式识别,人工智能等多学科技术知识.国内外的动态人脸识别监控系统都非常注重系统运 ...

  6. 《人脸识别原理及算法——动态人脸识别系统研究》—1章1.2节人脸识别相关学科的进展...

    本节书摘来自异步社区<人脸识别原理及算法--动态人脸识别系统研究>一书中的1章1.2节人脸识别相关学科的进展,作者 沈理 , 刘翼光 , 熊志勇,更多章节内容可以访问云栖社区"异 ...

  7. lacp静态和动态区别_静态人脸识别和动态人脸识别有哪些区别

    人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术.随着人脸识别技术的发展,在不同的实际应用场景会有不同的种类,比如说静态人脸识别和动态人脸识别,可应用在不同的场景中.这两者有哪些区别呢? ...

  8. 中控考勤机连服务器显示1007,中控智慧ZK-S1007动态人脸识别考勤门禁终端

    中控动态人脸识别ZK-S1007快速开闸多人同时通过闸机会议签到联网门禁机 中控动态人脸识别考勤门禁终端ZK-S1007 慧眼感知系列考勤门禁终端定位为功能丰富.扩展性强的面部指纹采集验证产品,达到更 ...

  9. 基于Java+MySQL 实现(Web)动态人脸识别的认证识别系统【100010315】

    摘 要 在人脸识别领域,主要涉及到两项技术,一项为人脸检测技术,另一项为人脸识别技术.其中,人脸检测技术主要解决存不存在人脸的问题,而人脸识别技术主要解决此人是谁的问题.除此以外,还有人脸对齐.人脸关 ...

最新文章

  1. ​causal-learn:基于Python的因果发现算法平台
  2. ETHNET DHCP的两种方式
  3. protobuf入门教程(六):导入定义(import)
  4. 【笔记】spring定时器时间配置实例
  5. 如何判断自己是否到了该辞职的时候
  6. 差分信号_形象解读差分信号,它比单端信号强在哪?
  7. java数据结构- - - -栈
  8. AMF序列化为对象和AMF序列化为二进制字节流
  9. qtreeview 点击二级节点弹出dialog_2019二级造价师开卷考?一顿操作猛如虎,一看分数59...
  10. 这5种数据挖掘技术,大数据玩的贼溜!
  11. 提供小图标(Icon)的网站(不定时更新)
  12. wps多出来的页面怎么办?wps怎么删除不要的页
  13. memcached介绍与作用和它的工作原理
  14. 多彩的书写工具,画图写字更好看,米家液晶小黑板多彩版上手
  15. C#中隐藏的15大功能
  16. 运用javascript写一个简单的点名系统!
  17. java计算平面度,关于平板平面度的计算方法?
  18. 既快又准并且低开销,一作亲解 MICRO 2021论文:一种自动化功耗模拟架构
  19. Starry的神奇魔法 矩阵快速幂
  20. 一阶差分序列garch建模_探讨黄金价格实证分析中ARIMA-GARCH模型的应用

热门文章

  1. html标签用于盲人,HTML 标签语义
  2. C++命名空间的形象化解释(详细)
  3. RotateAnimation类:旋转变化动画类
  4. 第十三章 软件系统结构(此章完结)
  5. 平台的理解,讨论如何构建企业系统平台
  6. c语言输入字符串输出ASCLL码值并且输出十六进制
  7. html模板中进行数学运算,??【程序中的数学】利用德摩根定律简化布尔运算
  8. php怎么设置浏览器提示错误,php如何让浏览器显示错误
  9. python中的大数据品牌运营策划营销_【干货】如何用大数据指导市场营销?请举出若干实际例子或者实用方法,而不是纯粹的理论?...
  10. 鑫磊股份深交所上市:市值39亿 为钟仁志与蔡海红夫妻店