人脸识别--活体检测(眨眼检测)

装逼专用图1.jpg

人脸识别在现在很多的项目中都有应用,最常见的就属此次315曝光的支付宝刷脸登录,当然支付宝也出来做了澄清,我们还是需要相信科技的.支付宝的刷脸可谓是相当成熟了.下面我们来简单的分析一下支付宝的刷脸登录流程.

** 1.前端采集人脸**

前端采集人脸的过程其实就是采集一张带有人脸的图像,然后我们对这个图像进行base64编码之后传给后台服务,后台服务去做人脸的识别,或者验证,如果这样的话,前端做起来其实是相对较复杂的,首先采集人脸的过程中,我们要做的是分析图片中有人脸然后将此图像保存,完成采集过程,当然这样是不安全的,因为我可以随便拿一个人的照片就可以骗过去前端采集的这一过程,所以如果仅仅如此做的话,还是比较简单的,在iOS中有苹果自带的识别人脸的API,当然现在用的最多的是opencv 但是这样做的话,那支付宝的产品和技术人员也就该卷铺盖回家了,所以我们需要在前端进行人脸采集的时候我们需要对识别到人脸进行活体检测,现在的活体检测技术有很多,有让摇头,有让张嘴,有人眨眼,当然也有让这些全部加起来的,(我的臆想..)就我自己的看法,出了眨眼都看起来有点奇怪,支付宝采用的就是眨眼来过滤掉静态图片的识别,但是我尝试过,如果把眨眼的视频拍下来来骗支付宝,是可以骗过去的哦,但是在后续的识别中却是通不过的,这点咱们在下个阶段再谈(你如果开通了支付宝的刷脸登录,可以录制一个自己的眨眼视频来骗下支付宝).支付宝的具体的采集人脸过程大概就是这样(个人理解,如果有人觉得不对的可以留言讨论哦)

** 2.后台服务验证识别**

其实后台的人脸识别验证不属于我们此篇文章要说的内容,在这儿我还是想大概的叙述一下,现在的后台人脸识别验证其实是有很好的第三方的,比较厉害的一个是"face++" 支付宝好像也有用face++ 的服务(face++ 的网站上有写),有兴趣的童鞋可以去网上搜一下,还有据我所知的讯飞,我有电联过讯飞的客服,他们有说他们的服务是基于face++的,识别率还是蛮高的,iOS,安卓都有封装好的对应的SDK,另外提一下face++人脸识别是基于接口的,当然如果自己公司想要开发自己的人脸识别服务也是可以的,但是就我知道的比较专业的好像就是opencv 了,不得不说opencv着实相当强大.

3.刷脸登录草图

我也大致写了下刷脸登录的流程草图,里面确实还有许多要优化的地方,也仅仅抛砖引玉了,希望可以帮助到需要的童鞋,(当初我做这块儿的时候,资料可谓少之又少,希望能够分享出来帮助一些正在迷茫的童鞋们)

Drawing4.png

4.划重点

重点是人脸识别中的活体检测
可以存在两种方式
1)客户端做人脸采集---本章重点
2)服务端做人脸采集---不会讲---类似于直播方式---服务端处理视频帧---有兴趣的童鞋可以尝试下,不知道体验好不好,没有那么强大的后台,所以只能做前端的眨眼检测了,但是即便服务器做,原理都是一样的吧.

5.检测思路

人脸采集的过程其实是客户端通过录像设备采集视频,然后我们拿到视频流,对视频流的每一帧做处理,进而来检测视频中是否有人脸和视频中的人脸是否---(再次感谢看远的github社区,感谢里面的人才,我可以把他们的思路借鉴下来)
(1)利用苹果自带的API(跟原生扫描二维码的类一样)来判断每一帧中是否有人脸,里面可以检测到两只眼是否存在以及两只眼是否睁开,然后记录上次睁开眼的时间,然后在下一次检测到闭眼的时候比较一下与上一次睁眼的时间差,如果在正常范围内则认为是一次正常的眨眼.---此方法,也还不错,但是误差较大,如果只是做一个眨盐拍照的娱乐应用还好,但是做活体检测就显得有点力不从心了.

(2)利用opencv首先对每一帧进行人脸检测,检测到后,算出眼镜的区域,截取眼镜区域再用opencv 对该图像中眼睛的数量进行检测,用一个数组来对每次的眼镜数量进行注册,当数组大小为3的时候,如果数组中第一次眼睛数量大于0,第二次等于0,最后一次大于0,则证明是一次眨眼,此方法可能很蠢,有专门做眨眼检测研究的可能会认为这种方法low到爆,可以利用阈值..大数据分析...反正那一堆堆高深的算法我是看不懂,前期也做过相对应的学习,但是实现起来太多复杂,领导给的时间不允许,所以就只有采用这种比较low的第二种方法了,不得不说这种方法效果还是蛮不错的,当然肯定比不上支付宝那种大牛写出来的算法,但是,至少可以信心满满的跟自己的领导交差了,可以半个小时之后,拿着demo去向领导邀功去了,然后坐上CEO,赢取白富美,从此走上人生巅峰的道路了,(没事,尽情的做梦吧)

6.代码就是王道

其实对于这块儿我已经封装成了一个服务CaptureFaceService
下面大概介绍一下这块儿的使用方法

  • 1.引入头文件--凑字数*
    #import "CaptureFaceService.h"
  • 2.创建对象 -- 凑字数 (懒加载)*
@property(nonatomic,strong)CaptureFaceService * captureFaceService;

  - (CaptureFaceService *)captureFaceService{
    if (!_captureFaceService) {
        _captureFaceService = [CaptureFaceService new];
    }
    return _captureFaceService;
}

  • 3.开始采集
- (void)startCaptureFace{
    __weak typeof(self)weakSelf = self;
    [self.captureFaceService startAutoCaptureFaceWithPreView:self.vidioView andCaptureFaceProgressBlock:^(float faceProgress, float eyeProgress, captureFaceStatus captureFaceStatus) {
        [weakSelf changeTipTextWithCaptureFaceStatus:captureFaceStatus];
    } andCompleteBlock:^(UIImage *resultImage, NSError *error) {
        if (error) {
            UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"检测人脸失败,请重试" message: nil preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"重试" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                [weakSelf startCaptureFace];
            }]];
            [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {
            }]];
            [weakSelf presentViewController:alertController animated:YES completion:nil];
            return ;
        }
        //处理采集到的图片
        [self handleResultImage:resultImage];
    }];
}
  • 4.当然也可以中断采集
    [self.captureFaceService stopCaptureFace];

7.深度剖析

说实话,我真的想做一下深度的剖析,活体检测听起来太过高大上,我裤子都脱了,竟然给我看这个.这个.好吧,简答的做个介绍吧!---其实真的写的很简单,为了满足你们,我就凑点字数吧

#import <Foundation/Foundation.h>
#import <opencv2/highgui/cap_ios.h>
typedef enum
{
    captureFaceStatus_NoFace,       //未检测到脸
    captureFaceStatus_MoreFace,     //有多张脸
    captureFaceStatus_NoBlink,      //未眨眼
    captureFaceStatus_IllegalData,  //检测非法
    captureFaceStatus_OK,           //检测完成
    captureFaceStatus_NoCamare     //检测完成

}captureFaceStatus;

typedef void (^captureFaceProgressBlock ) (float faceProgress,float eyeProgress,captureFaceStatus captureFaceStatus);
typedef void (^captureFaceCompleteResultBlock) (UIImage *resultImage,NSError * error);
@interface CaptureFaceService : NSObject <CvVideoCameraDelegate>


/**
 开启智能扫描人脸(包含活体检测--眨眼)

 @param preView 视频预览区域
 @param captureFaceProgressBlock 过程回调
 @param captureFaceCompleteResultBlock 完成回调
 */
- (void)startAutoCaptureFaceWithPreView:(UIView *)preView andCaptureFaceProgressBlock:(captureFaceProgressBlock)captureFaceProgressBlock andCompleteBlock:(captureFaceCompleteResultBlock)captureFaceCompleteResultBlock;


/**
 停止采集
 */
- (void)stopCaptureFace;
@end

8.相信我了吧真的没有什么可以剖析的

什么,你想看我里面是怎么实现的?里面也总共200来行代码,贴出来浪费看官的流量,我就不再帖代码了,看到这里,你就可以拿出来我这个类来使用了,demo我会放到github上,有需要的童鞋可以去下载研究实现哦.

9.有一大波重点来袭 -- (重点)

demo下载下来是不可以直接使用的,对你没有听错,会报错,你根本跑不起来(你他么是不是在逗我,我需要下载下来直接能跑的程序,...)看官切勿烦躁,因为opencv 这个SDK太大,150多兆,,,git真的上传不上去啊,所以,按照以下步骤做,您所下载的程序就可以跑起来了

1.去opencv 官网,下载iOS的SDK,我demo中用的是2.4版本
<a>http://opencv.org/releases.html</a>
2.去度娘 (haarcascade_frontalface_alt2.xml) (haarcascade_eye.xml)这两个级联分类器并下载导入到自己的项目中
3.这下您就可以开心的跑起来体验了....

10.重点中的重点

源码直通车

装逼专用图2.jpeg

11.希望能帮助到需要的童鞋,如您喜欢,敬请留言

推荐阅读更多精彩内容