上一篇,一切顺利的话,你从github上clone下来的整个工程应该已经成功编译并生成dll和exe文件了;同时,ImageMagic程序亦能够打开并编辑图像了,如此,证明接下来的操练你不会有任何障碍。开篇序文已经说过,工具库缘起人脸识别。我开博后的第一个系列讲了TensorFlow下的人脸识别,写完之后就觉得方向错了,那个系列采用的方案其实更适合物体检测、分类,而不是人脸识别。所以,基于历史原因,我决定这个系列还是从人脸识别开始,让诸君看看改进后的方案到底是怎样的。首先声明,改进后的方案参考了如下一篇博文:

https://blog.csdn.net/mr_curry/article/details/52443126

方案的基本原理及核心算法参照该博文实现,并不是本人原创,要感谢该篇博文的作者。只不过有些遗憾的是,该作者并没有在blog上提供完整代码(少了一个函数),且提供的代码亦存在些许错误;同时,对同一张图片的多次预测结果并不一致,存在计算结果溢出的情形。虽如此,但还是要感谢博文作者,核心算法很明了,且有效,再次感谢!我在原文的核心算法基础上,按照我自己的设计原则做了重构和编码,除了算法原理,代码和结构与原文完全不同,请诸君注意

我自己的学习习惯是——先看效果,然后再决定是否跟进研究此项技术,我想诸君大抵以如此。故,我们先运行一下程序看看效果如何。事先声明,如果你在接下来的操作中出现任何问题,请回头阅读该系列第一篇文章,确定完全达成第一篇的目标后再来这里。前文已经说过,EXE工程“WhoYouAre”即为图像级的人脸识别应用,因此,你应当在工程的输出目录“MachineVisionLib\x64\bin”下看到该应用程序的可执行文件:“WhoYouAre.exe”,如下图:

在该文件夹空白处,按住键盘“Shift”键不要松开,然后鼠标右键菜单选择“在此处打开命令窗口(W)”,如此,我们进入windows控制台:

为了将来能够看到完整的控制台输出信息,建议你鼠标左键点击控制台窗口左上角的图标,在弹出的菜单中打开“属性”窗口,将控制台“布局”设置大一些,最好能够占满整个屏幕,这样你才能看到完整的程序输出信息。设置完毕后,请在控制台输入:

WhoYouAre

控制台会输出该程序的Usage信息:

看着有很多选择,其实就人脸注册和人脸识别两项功能而已。这么多的选择只是为了编码方便,因为视频文件、视频流和图像(照片)在实际处理上均有些许不同,需要单独处理,所以选择看起来就比较多了:

                                    WhoYouAre.exe add 使用照片注册人脸

                               WhoYouAre.exe predict 使用照片进行预测,控制台输出预测结果(人名和概率)

                       WhoYouAre.exe ocvcamera 通过捕获USB/WEB摄像头的实时视频进行人脸识别,参数值为摄像头序号,播放器为OCV自带播放器——ffmpeg

                           WhoYouAre.exe ocvvideo 通过视频流进行预测,参数值为视频地址,可以是本地的视频文件或rtsp地址,播放器依然是OCV自带播放器

    WhoYouAre.exe vlcvideo_rtsp_predict 通过捕获rtsp实时视频进行人脸识别,参数值为rtsp地址,播放器为libvlc播放器

              WhoYouAre.exe vlcvideo_predict 通过本地视频文件进行人脸识别,参数值为本地视频文件名

WhoYouAre.exe vlcvideo_rtsp_catchface 通过rtsp视频流检测人脸并注册到人脸库,参数值为rtsp视频流地址

         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

直接注册人脸。第一种方式不再赘述,关于第二种方式,操作其实很简单。首先,WhoYouAre不支持USB/WEB摄像头的直接注册,仅支持rtsp流的直接注册。如果你手头只有USB/WEB摄像头,那么需要先录制一段包含你的人脸的视频,然后输入第一条指令(xx.avi换成你的视频文件名)即可进行人脸注册。如果你有网络摄像头,则输入第二条指令即可。当然,别忘了将rtsp地址换成你自己的地址。无论你使用哪条指令,WhoYouAre程序都会弹出播放界面,并将检测到的人脸用矩形框框出。你可以根据框出的人脸清晰度来判定是否满足注册要求,如满足,则立即按键盘“回车”键。此时,框出的人脸会被截取到一个单独窗口中显示,继续“回车”则当前这张人脸将被注册到系统中:

其实整个人脸注册操作就是找到人脸后的两个“回车”,之后,我们会在控制台看到相应的输出信息:

提示“Face-0”已被添加到人脸库中。此时我们还需要将这个“Face-0”改为正确的名字,打开“x64\bin\PERSONS”文件夹,找到“Face-0.xml”,将其重新命名为你自己的名字即可,比如“Neo.xml”。然后,再回头修改“x64\bin”目录下的“FACEDB_STATISTIC.xml”文件,将“PERSONNAME_TOTAL_LENGTH”标签下的人名总长度改为修改后的长度。比如原来是74个字节,名字改为“Neo”后,比“Face-0”少了3个字节,那么人名总长度就要减去3个字节,变为71。这样,就完成了视频人脸注册的过程。

接下来我们就测测视频识别的性能表现如何。先是CPU模式,控制台输入如下指令:

WhoYouAre ocvvideo xx.avi

回车,程序执行后我们注意观察控制台输出,会发DNN网络的特征提取时间比较长,大约在600-700毫秒之间:

也就是说,只要视频帧中检测到人脸,那么这一帧的画面就要在人眼中存留600-700毫秒,然后才能切换到下一帧,这样的延时会带来怎样的播放效果呢:

果然,视频中的美女变成了“树懒”,表情变化过程看得那叫一个真呐!同样,我们使用libvlc播放器(指令:WhoYouAre vlcvideo_predict xx.avi)耗费的时间与OCV自带播放器差不多,也是在600-700毫秒之间。只不过当我们使用rtsp流进行人脸识别时,OCV播放器就表现很差了(指令:WhoYouAre ocvvideo rtsp地址),基本上会出现连续掉帧的情形,同时,控制台输出也惨不忍睹:

此时不仅播放都成问题,别说实时识别人脸了,所以实时视频流识别我们需要采用libvlc播放器(指令:WhoYouAre vlcvideo_predict rtsp地址),本地视频文件识别两种播放器均可。那么,GPU模式下视频识别的效果如何呢?首先将程序切换到GPU模式,然后再次输入“WhoYouAre.exe ocvvideo xx.avi”,程序执行结果如下图所示:

动作依然明显变缓,只不过比CPU模式要好很多,至少不是“树懒”了。那么问题来了,GPU模式都这样的话,时间到底去哪儿了呢?我们来看一下播放上述视频时控制台的输出:

程序在两个地方计时,一个是总的预测时间(Time spent of predict),另一个是DNN网络提取特征的时间(Execution time of caffe net Forward())。每一帧的总预测时间包含了特征提取时间,很明显特征提取时间在其中占比很小,甚至可以忽略不计。但总时间始终维持在在60-80毫秒之间,而我播放的这个视频的帧率为24,也就是每帧间隔40毫秒多一点,超过这个时间就会使得视频呈慢动作状态。显然,我们看到的播放效果与计算结果一致——预测时间太长了,使得正常的视频播放都变慢了。那么这个时间到底花费在了哪里呢?其实,时间花费在了人脸检测、Dlib库68个人脸特征点提取上,至于这两个地方具体花费了多少时间需要我们在源文件的相应位置添加性能监测代码才可。关于这一点,我将在后面讲解人脸识别模块的编码实现时详细描述,本文不再细究。

机器视觉及图像处理系列之二(C++,VS2015)——图像级的人脸识别(1)的更多相关文章

  1. 机器视觉及图像处理系列之一(C++,VS2015)——搭建基本环境

    自<人脸识别>系列发布至今,已一年多矣,期间除答复些许同好者留言外,未再更新文,盖因项目所迫,不得已转战它途,无暇.无料更博耳.其时,虽人已入项目中,然终耿怀于人脸识别方案之谬.初,写此文 ...

  2. Home Assistant系列 -- 接入手机摄像头做实时监控和人脸识别

    准备一部废旧(土豪忽略,主要是穷)的.摄像头还是好的手机做监控设备,(Android 和iPhone都行)当Home Assistant 获得实时的视频流后,可以接入各种图像处理组件完成人脸识别,动作 ...

  3. OpenCV2+入门系列(二):图像的打开、创建与显示(命令行)

    前置知识:数字图像的简略知识 这里只是最基础的知识,上课如果稍微听了课的同学可以直接略过不不看. 彩色图像: 对于一副数字图像,对于一副RGB色彩空间的彩色数字图像,它一共有宽X高个像素格子,每个格子 ...

  4. Android视频录制从不入门到入门系列教程(二)————显示视频图像

    1.创建一个空的工程,注意声明下列权限: <uses-permission android:name="android.permission.CAMERA"/> < ...

  5. 人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型

    人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型 经过前面稍显罗嗦的准备工作,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的te ...

  6. android图像处理系列之四-- 给图片添加边框(上)

    图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下 ...

  7. android图像处理系列之五-- 给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

  8. android图像处理系列之四--给图片添加边框(上)

    图片处理时,有时需要为图片加一些边框,下面介绍一种为图片添加简单边框的方法. 基本思路是:将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下 ...

  9. android图像处理系列之五--给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

随机推荐

  1. UNIX高级环境编程(12)进程关联(Process Relationships)- 终端登录过程 ,进程组,Session

    在前面的章节我们了解到,进程之间是有关联的: 每个进程都有一个父进程: 子进程退出时,父进程可以感知并且获取子进程的退出状态. 本章我们将了解: 进程组的更多细节: sessions的内容: logi ...

  2. 美式九球比赛规则 (Nine-ball)

    九球比赛规则 (Nine-ball) 九球比赛规则 一.器材: 1.台面规格: a.内沿长254厘米. b.内沿宽127厘米. c.高80厘米. d.角袋口内沿最近距离为10.5厘米(±1毫米),腰袋 ...

  3. 向磁盘写入数据提示:No spac left on device通过df -h查看磁盘空间,发现没满,解决方法

    初步判断应该有两种情况:一种是block满了,另一种情况就是inode耗尽了. 首先df -i 查看一下是否耗尽inode/block数量. 虚拟一块磁盘并格式化: dd if=/dev/zero o ...

  4. Coursera-AndrewNg(吴恩达)机器学习笔记——第三周编程作业(逻辑回归)

    一. 逻辑回归 1.背景:使用逻辑回归预测学生是否会被大学录取. 2.首先对数据进行可视化,代码如下: pos = find(y==); %找到通过学生的序号向量 neg = find(y==); % ...

  5. PHP 与 YAML

    PHP 与 YAML 这一段时间都没有写blog,并不是因为事情多,而是自己变懒了.看到新技术也不愿意深入思考其背后的原理,学习C++语言了近一个多月,由于学习方法有问题,并没有什么项目可以练手.靠每 ...

  6. fedora27安装谷歌浏览器Chrome

    安装 添加chrome源 #cd /etc/yum.repos.d #wget http://repo.fdzh.org/chrome/google-chrome-mirrors.repo 安装Chr ...

  7. 一、Ajax 二、JSON数据格式 三、Ajax+Jquery 四、分页的实现

    一.Ajax概述###<1>概述 ###<2>组成 以XMLHttpRequest为核心,发送Ajax请求和接收处理结果 以javascript为语言基础 以XML/JSON作 ...

  8. October 20th 2017 Week 42nd Friday

    My life is in these books. Read these and know my heart. 我的人生就在这些书中,读完他们就能读懂我的心. Some people say tha ...

  9. SVG绘制图形

    一.SVG介绍 1.SVG指可伸缩矢量图片 2.SVG用来定义用于网络的基于矢量的图形 3.SVG使用XML格式定义图形 4.SVG图像在放大或改变尺寸的情况下其图形质量不会有损失 5.SVG是万维网 ...

  10. Spark项目之电商用户行为分析大数据平台之(八)需求分析

    1.按条件筛选session 搜索过某些关键词的用户.访问时间在某个时间段内的用户.年龄在某个范围内的用户.职业在某个范围内的用户.所在某个城市的用户,发起的session.找到对应的这些用户的ses ...