人脸识别技术低成本应用(概述篇)

这些年人脸识别技术落地开花,早已经算不上什么高科技了。很多对人脸识别要求不高的应用场景,其实不一定需要高价购买商业算法,开源方案可能就能满足需求。例如:统计人流量、刷脸打卡之类的应用场景,只要解决基本的人脸检测和人脸比对就可以了。在人脸检测和人脸特征比对两个方面,其实有很多可用的开源方案。

当然,开源方案不代表零成本,把开源方案用起来还是需要花费一些时间和精力的,好处就是用好了,就有了一套自己可以业务需求进行调整和优化的人脸识别方案。

先上个截图看效果,demo源码放github上了,有兴趣的可以自己编译出来看看,懒得编译的可以直接下载APK包体验。

人脸识别技术低成本应用(概述篇)_第1张图片

 

图中体现了在android平台上的三种人脸识别技术:手机摄像头自带的人脸检测、opencv dnn人脸检测、tensorflow facenet人脸特征提取比对。

绿色框是手机摄像头自带的人脸检测结果,黄色框是opeccv dnn执行tensorflow人脸检测模型的人脸检测结果,蓝色框是参考手机摆放角度调整以后的人脸位置,下排三张图从左至右分别是:人脸比对基准图、当前识别帧图中比中的人脸截图、当前识别帧图中没有比中的人脸截图。

先简单说一下手机摄像头自带的人脸检测。准确度很好,除了能把人脸框出来,还能识别眼睛和嘴的点位,虽然不是所有手机都支持,但估计现在还能用的android手机绝大部分都是支持的,至少在一台红米7的旧机器上测试也是支持人脸检测的。手机摄像头自带人脸检测最大的优势是快,人脸信息几乎是跟视频帧同步获取的,可以理解为0耗时。难点在于用好camera2,网上资料虽然多,但很少讲到点子上,这里先按下不表,后续再整理一篇文章好好吐槽一下。

如果是在APP中应用人脸识别技术,摄像头自带的这个人脸检测功能还是要用好,因为快就意味着省电,也意味着可以把体验做得很流畅,这两点基本决定了一个APP的品质。

opencv的人脸检测方案其实不止一套,网上说的比较多的是人脸分类器,而我选择的是通过opencv dnn网络加载tensorflow人脸识别模型,两类方案识别准确度差不多,但是后者效率远高于前者。opencv人脸检测方案android端和PC端通用,引用不同版本的opencv即可,但是就java而言,两个平台的opencv java封装不完全一样,尤其是PC端除了opencv官方的java库,还另有一套第三方的javacv,虽然都是玩Mat,但Mat和Mat却不尽相同。

谈到Mat也多说几句,Mat是opencv一个非常核心的概念,本质是把一维的内存数据定义为多维的矩阵数据来用,例如:一张10x20的RGB位图,用Mat描述就是一个20行10列3通道的3维矩阵。对于刚接触的java或android开发者而言,Mat概念会有个理解过程,不然即使从网上copy一段能用的代码,也会用得一头雾水。好在网上资料很丰富,有兴趣的可以多找些帖子看看,这里就不赘叙了,另写一篇如何用opencv dnn实现人脸检测的文章再对照着代码讲吧。

opencv dnn人脸检测的效果优于手机摄像头自带的人脸检测,一是误判率很低,二是定位很准,单从这两点看,opencv dnn甚至不输于市面上的一些商业人脸检测算法。摄像头自带的人脸检测个人猜想是用的目标跟踪类算法实现的,快是快,但是检测出来的人脸位置与帧图之间存在若干毫秒的延迟,运动状态下的人脸检测,位置会有一定的偏移。opencv dnn人脸检测因为是针对单张图片做处理,因此不存在错位的问题,但效率方面就差远了,在华为meta30pro上实测640x480尺寸图片检测耗时70-110毫秒。在效果优先或者摄像头不支持人脸检测的应用场景,opencv dnn人脸检测是一个非常靠谱的解决方案,而且android、linux、windows各个平台都可以用。

tensorflow facenet是在检测到人脸以后,用来提取人脸特征的。tensorflow不消说了,地球人都知道是干啥用的,facenet简单的讲是一种提取人脸特征的算法模型,网上有很多实现版本,基于效率考虑,我选择了一个基于MobilenetV1网络实现的facenet版本。在tensorflow2 python中转换为lite格式以后,在meta30pro上实测提取一张裁剪好的人脸图片特征耗时约20-30毫秒。特征比对因为只是计算两个128维向量的欧式距离,耗时几乎可以忽略。

tensorflow的专业性和复杂度与opencv是一个级别的,有时间也另写一篇文章详说facenet在Java和android上实现人脸特征提取的心得和槽点吧。这里先直接说效果:从CASIA-WebFace数据集中抽取300个人约20000张人脸照片做全比对测试,准确率超过97%,跟一些商业算法三个9四个9的准确率比起来还是有些差距,但用来实现一些常规应用则完全够用了。

有了靠谱的人脸检测和人脸特征提取算法,实现人脸识别相关的应用需求就不难了,但还是有些关联问题也需要关注:

  1. 容错问题。即使是商业算法也存在误判的情况,只是概率有高低,大多数误判主要是由帧图失焦、人脸角度偏离过大、光照度太高或太低引起,如果只是简单的逐帧处理,即使0.1%的误判率在应用效果上也会体现的比较明显。

  2. 人脸检测算法与人脸特征提取算法之间的鲁棒性差异问题。试过的几个人脸检测算法,鲁棒性都非常好,就是人脸丢失率都很低,模糊脸、半张脸、侧脸都能被检测到,这些脸抠成小图交给特征提取算法也是能生成特征值的,但却没法作为正确的人脸相似度判断依据了,暂时也没有很好办法彻底排除这种情况,只能在具体应用上通过业务逻辑的容错性解决。

  3. 性能问题。性能问题并不是人脸识别的特有问题,但是人脸识别相关应用中会体现得比较突出。例如我上面提到的tensorflow facenet,提取一个人脸图片特征耗时只需20-30毫秒,但是如果在应用中很随意的对bitmap或者BuffedImage进行一些预处理,预处理的耗时可能会接近人脸特征提取的耗时,那么在视频应用中就会表现出很难看的帧率。

你可能感兴趣的:(android,dnn,tensorflow)