在上一篇的0基础用OpenCV做人脸识别示例中, 我用了OpencCV来获取摄像头的影像并识别出人脸。但其实也是侦测出人脸在画面中的位置,离真正的通过人脸识别出人的身份还差很远。接下来的几篇文章,我打算朝着这个牛逼哄哄的方向,继续努力,打造出一个智能机器人来完成整个人脸识别的流程,包括侦测、记录、识别、修改。
face-recognition初识
自从第一眼看到face recognition的介绍后,就感觉它的功能已经非常逆天了。从其网上的例子可以了解到 ,其实人脸识别的建模已经有现成的了,可以直接拿来用;而相应侦测、识别、比较也已经有现成的API可以调用了,我们只要关注自己的业务实现就好。可以看一下它的官网的一个例子就知道人脸识别的开发有多方便:

从这个例子的源码, 我们可以知道,它的大概实现流程是:
- 从静态图片中抽取好人脸特征值,并定义好相应的名字,构建一个矩阵变量来存储人脸库
- 获取摄像头的输入,针对某些帧,识别其中人脸
- 拿实时识别出来的人脸特征值和人面库中的做比较,得到最接近的人脸名字
- 用cv2把人脸位置用一个方框框出来,并加上相应的名字标签
细心的朋友可能会注意到上面‘针对摄像头的某些帧’,为什么这么说?因为从范例的代码可以看到它把识别人脸和绘制人脸定位方框分开了。绘制人脸方框每一帧都会做,但不是每一帧都做人脸识别的,而是隔一帧做一次。没做人脸识别的那帧就拿上一帧识别出的人脸信息(如果有的话)来绘制显示信息。我想是因为性能上考虑,避免人脸识别引起画面的卡顿,范例给我们示范了其中一种优化的方式。其实也没有必要每一帧都做人脸识别,人眼是感觉不出来的。我改造后的程序是隔5帧才识别一次,对用户体验来说也没什么影响,而且出来的效果让人相框带有一种“吸附感”,感觉更真实。
问题与需求
好了,刚上的范例已经完美地带我们进入人脸识别的开发领域。接下来,我们就要思考如何改造,让它变成一个简单有趣的玩具咯。我一开始就拿着示例按着自己的感觉乱改一通,发现还是有很多可以改进的地方的, 如:
- 人脸识别的精度太低了,代码的逻辑是在人脸库中轮询匹配到首个差距小于0.6的,出来的效果是,很容易把一张新脸蛋误认为是人脸库中的某人;
- 人脸库的数据来自于本地的静态图片,如果要加入新脸蛋,就必需要拍照、存放目录、在代码中加入数据、重启程序,这样的用户体验太差了,根本不能吸引人玩;
- 还有是用户体验,我是用mac book来把玩的,相当于是用前置摄像头,这样跑起来的显示效果是左右手相反的,就是罗胖所谓的“别人眼中的你”,看起来很别扭。其实,这种场景应该显示为“镜子中的你”效果会比较自然;
改造工作内容
接着,我们把以上用户的问题拆解分类一下,转化成码农要干的事情(story),可以按以下分类:
精度的提高
- 缩小特征比较的差距阀值
- 改进比较算法,在保障性能的前提下,应该比较更多的人脸,务求拿到最接近的一个
提高数据(人脸库)的维护效率
- 把人脸的特征值和人名关联并存储起来,而不是在每次程序启动时通过识别静态图片来获取
- 当遇到未知人脸时,让用户可以即时录入
提升用户体验
- 支持镜面效果显示
- 显示匹配度
- 支持多用户识别和名字关联
代码优化
- 代码可读性太差了,有待重构和封装
- 提取重要配置参数,便于以后更好的测试、参数调试
OK,说了这么多,感觉自己不是在说人脸识别,而是在做需求分析。。。。哈哈!Anyway, 以上就是对这个人脸识别小助力打造的前期调研、需求分析和功能开发的拆解。在接下来的两篇文章,我会总结回顾我理想中的人脸识别玩具是怎么改造出来的。