趁空闲时间,记录一下做过的一个实验室项目,主要分为4个部分:1)语音转文字;2)人脸识别;3)行人识别;4)检索。本人负责人脸识别和检索模块及整体项目的融合,在此介绍一下自己所做的两个模块。
对于现今摄像录影众多的情况,想了解一个人是否在某个时间段内出现过以及出现的时间等信息,以往需要大量的人力去查找。针对于这个问题,我们开发了一个人脸检索系统,可以快速的定位到此人是否出现,出现在什么时候等信息,以此来解决需要耗费大量人力的问题。
- 使用opencv读取视频,每隔25帧进行一次人脸特征提取(视频帧数为25,如果每帧都处理不是很合理,1是会出现很多重复的人脸,2是人脸识别算法fps速度不够,会产生卡顿)
- 使用人脸检测算法对视频帧进行检测及提取人脸特征
- 使用Faiss索引库构对提取到的人脸特征加入索引构建特征数据库
- 使用Flask框架实现前后端的交互传输
1. 人脸识别算法
项目中尝试了Opencv、Dlib、Mtcnn+FaceNet的算法,最后选定了Mtcnn+FaceNet算法,优势是在小脸和侧脸方面检测更优。
Mtcnn【输入:图片帧;输出:检测到的人脸框、置信分数、5个关键点位置】 FaceNet【输入:160x160大小的人脸图片(按Mtcnn检测到的人脸框裁剪,根据关键点进行人脸对齐,再resize成160x160大小); 输出:人脸特征(128维)】
1.1 Mtcnn算法
参考:Mtcnn详解
mtcnn网络主要分为4个阶段:图像金字塔、PNet、RNet、ONet
- 图像金字塔:
输入一张图片,将图片resize到500,然后按照factor = 0.709依次缩小裁剪至图片大小为12,将所有图片保存
- PNet:
针对每一张图片,依次输入PNet,输出很多个粗略的候选框(每个框有位置信息还有置信分数),将每个图片的候选框合并,然后进行NMS算法,得到一些粗略的proposal
- RNet:
将PNet得到的proposal裁剪并resize成24x24大小,输入Rnet,然后进行NMS,得到较准确的rois(位置和分数)【RNet的NMS阈值设置为0.3,只剩下少了的rois了】
- ONet:
将RNet得到的较准Rois裁剪并resize成48x48大小,输入ONet,然后进行NMS,得到最终的rois,即rectangles。 【len(rectangles) 的个数为检测到的人脸数,len(rectangles[0])为15,4:框的位置坐标,1:置信分数,10:5个关键点的坐标】
1.2 FaceNet算法
根据Mtcnn的输出结果,在原图片上进行裁剪人脸,并进行人脸对齐矫正,随后使用FaceNet算法的backbone对裁剪后的人脸进行特征提取(128维),其网络模型就是InceptionResNetV1,比较容易,这里就不详细讲了 FaceNet的triple loss:Facenet介绍 【注,常见的对齐方法:通过双眼坐标进行旋正、通过矩阵运算求解仿射矩阵进行旋正】
2. Faiss
使用faiss索引库对提取到的人脸特征加入索引构建数据库
- 代码实现(faiss快速入门)
- faiss构建数据库的优点(参考)
- faiss专门提供向量存储搜索等相关服务,支持索引的动态增删
- 良好的搜索效率和内存占用:128/100万/0.024ms/1.552GB;128/500万/0.047ms/5.504GB
- 支持多种相似度索引方式
3. Flask
使用Flask进行前后端的交互功能
- 代码实现(入门教程很多,就不贴了…)