接,一切顺利的话,你从github上clone下来的整个工程应该已经成功编译并生成dll和exe文件了;同时,ImageMagic程序亦能够打开并编辑图像了,如此,证明接下来的操练你不会有任何障碍。开篇序文已经说过,工具库缘起人脸识别。我开博后的第一个系列讲了TensorFlow下的人脸识别,写完之后就觉得方向错了,那个系列采用的方案其实更适合物体检测、分类,而不是人脸识别。所以,基于历史原因,我决定这个系列还是从人脸识别开始,让诸君看看改进后的方案到底是怎样的。首先声明,改进后的方案参考了如下一篇博文:
方案的基本原理及核心算法参照该博文实现,并不是本人原创,要感谢该篇博文的作者。只不过有些遗憾的是,该作者并没有在blog上提供完整代码(少了一个函数),且提供的代码亦存在些许错误;同时,对同一张图片的多次预测结果并不一致,存在计算结果溢出的情形。虽如此,但还是要感谢博文作者,核心算法很明了,且有效,再次感谢!我在原文的核心算法基础上,按照我自己的设计原则做了重构和编码,除了算法原理,代码和结构与原文完全不同,请诸君注意。
在该文件夹空白处,按住键盘“Shift”键不要松开,然后鼠标右键菜单选择“在此处打开命令窗口(W)”,如此,我们进入windows控制台:
为了将来能够看到完整的控制台输出信息,建议你鼠标左键点击控制台窗口左上角的图标,在弹出的菜单中打开“属性”窗口,将控制台“布局”设置大一些,最好能够占满整个屏幕,这样你才能看到完整的程序输出信息。设置完毕后,请在控制台输入:
WhoYouAre
控制台会输出该程序的Usage信息:
看着有很多选择,其实就人脸注册和人脸识别两项功能而已。这么多的选择只是为了编码方便,因为视频文件、视频流和图像(照片)在实际处理上均有些许不同,需要单独处理,所以选择看起来就比较多了:
WhoYouAre.exe add 使用照片注册人脸
WhoYouAre.exe predict 使用照片进行预测,控制台输出预测结果(人名和概率)
WhoYouAre.exe ocvcamera 通过捕获USB/WEB摄像头的实时视频进行人脸识别,参数值为摄像头序号,播放器为OCV自带播放器——ffmpeg
WhoYouAre.exe vlcvideo_predict 通过本地视频文件进行人脸识别,参数值为本地视频文件名
WhoYouAre.exe vlcvideo_catchface 通过本地视频文件检测人脸并注册到人脸库,参数值为本地视频文件名
这些选项中,几个视频预测选项在CPU模式下存在卡顿、掉帧的问题,主要是因为人脸检测与识别处理花费了太长的时间;GPU模式下,GTX 1050Ti显卡加速测试,帧率(FPS)高于15帧时视频播放开始呈现太空漫步状态,动作明显变慢,识别性能同样表现不佳。至于时间到底耗费在了哪些处理上,我会在后面的篇幅中详细讲解,让我们先看看图片预测的效果。
在第一篇clone的工程中,“x64\bin\FACE-PICS”文件夹下是我做测试的图片,除了两个国外的电影明星,其他三人均是牛人,特别是黄老和袁老,更是民族的脊梁,吾辈之楷模。我们第一步要做的工作就是要先将他们注册到我们的系统中。首先,在“x64\bin”文件夹下建立“PERSONS”文件夹,保存人脸特征数据:
然后,控制台输入如下指令:
WhoYouAre add .\FACE-PICS\HuangXuHua.jpg "Huang Xu Hua"
回车执行,我们会看到控制台输出了一大串信息,这些信息包括DNN网络结构以及预训练模型被加载时的调试输出信息。一切顺利的话,我们会在这一大串信息的尾部看到黄老被成功添加到系统中的提示信息:
此时,“PERSONS”文件夹下面会出现“Huang Xu Hua.xml”文件,这个文件保存的就是黄老脸部的特征数据:
该文件的主要内容就是2622个脸部特征值,浮点数:
而在“x64\bin”下面则多了一个“FACEDB_STATISTIC.xml”文件,它是系统的统计文件,用于记录系统已注册的人脸数量以及人名长度。它存在的意义就是为了简化算法实现,节省系统资源。关于它的使用方法,我会在讲解算法实现时再说。至此,第一个人脸已注册完毕。当然,只注册一个人脸是远远不够的,要想测试算法的可靠性,接下来我们还需要将其余几人注册到系统中,最终的注册结果如下:
统计文件“FACEDB_STATISTIC.xml”的内容变成了这样:
统计文件的内容很直观,我们总共添加了5个人,人名总长度67个字节。
人脸注册完毕,接下来该是试试效果了。控制台输入如下指令:
WhoYouAre predict .\FACE-PICS\YuanLongPing-1.jpg
回车执行,我们会看到和注册时类似的输出信息,稍等几秒, 我们同样会在控制台输出信息的尾部看到预测结果:
在已经存在5个人的人脸库中,程序还是顺利找到了袁老,相似度为0.869506,基本上相似度超过85%就可以确定是这个人了。上图中还有两个数据需要关注(红色箭头所指处),这两个数据统计的是本次人脸识别花费的时间,其中1009.4ms统计的是总时间,782.14ms统计的是DNN网络提取脸部特征数据花费的时间。从数据上看,时间花费很可观,基本上1秒识别一张。当然,必须告诉你的是,这是CPU模式下的时间统计,那么GPU模式下会怎么样呢?很简单,将程序切换到GPU模式下(关于如何切换到GPU模式,请看),再执行一次看看效果:
时间明显变小,1秒至少能处理4张了。需要特别提醒的是,这个时间其实还可以再缩小,因为在这里我使用的人脸检测函数是ShiQi.Yu老师的libfacedetection,它在检测人脸时耗时很大,caffe的人脸检测预训练模型要比这小很多,因此视频检测我就使用了caffe预训练模型。如果你有时间,可以把这部分代码调整为预训练模型方式。不过,无论何种方式,CPU与GPU模式在识别性能上的差距均非常明显,特别是在视频识别上,两者差距异常明显。
为了直观感受视频识别的性能问题,现在需要把自己注册到系统中了。有两种方式注册自己:一种是使用自己的照片,按照上面介绍的步骤注册人脸;第二种是通过摄像头录制一段视频或直接捕获摄像头视频流,然后在控制台输入如下指令:
WhoYouAre vlcvideo_catchface xx.avi
或
WhoYouAre.exe vlcvideo_rtsp_catchface rtsp://xx.xx.xx/h264/ch1
其实整个人脸注册操作就是找到人脸后的两个“回车”,之后,我们会在控制台看到相应的输出信息:
接下来我们就测测视频识别的性能表现如何。先是CPU模式,控制台输入如下指令:
WhoYouAre ocvvideo xx.avi
回车,程序执行后我们注意观察控制台输出,会发DNN网络的特征提取时间比较长,大约在600-700毫秒之间:
也就是说,只要视频帧中检测到人脸,那么这一帧的画面就要在人眼中存留600-700毫秒,然后才能切换到下一帧,这样的延时会带来怎样的播放效果呢:
动作依然明显变缓,只不过比CPU模式要好很多,至少不是“树懒”了。那么问题来了,GPU模式都这样的话,时间到底去哪儿了呢?我们来看一下播放上述视频时控制台的输出:
程序在两个地方计时,一个是总的预测时间(Time spent of predict),另一个是DNN网络提取特征的时间(Execution time of caffe net Forward())。每一帧的总预测时间包含了特征提取时间,很明显特征提取时间在其中占比很小,甚至可以忽略不计。但总时间始终维持在在60-80毫秒之间,而我播放的这个视频的帧率为24,也就是每帧间隔40毫秒多一点,超过这个时间就会使得视频呈慢动作状态。显然,我们看到的播放效果与计算结果一致——预测时间太长了,使得正常的视频播放都变慢了。那么这个时间到底花费在了哪里呢?其实,时间花费在了人脸检测、Dlib库68个人脸特征点提取上,至于这两个地方具体花费了多少时间需要我们在源文件的相应位置添加性能监测代码才可。关于这一点,我将在后面讲解人脸识别模块的编码实现时详细描述,本文不再细究。