转自:http://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=402840844&idx=1&sn=25cce8cdd0d6403943074bce18949b61&scene=23&srcid=0412qbNrW1nazc9f8h0tRljV#rd
本文分上下两篇,上篇主要介绍人脸检测的基本流程,以及传统的VJ人脸检测器及其改进,下篇介绍基于深度网络的检测器,以及对目前人脸检测技术发展的思考与讨论。为了节省篇幅,文中略去了对具体参考文献等的引用,读者可以通过相关的关键词去搜索对应的论文。为了让本文更适合非计算机视觉和机器学习背景的读者,文中对所涉及到的专业术语尽量以通俗的语言和用举例的方式来进行解释,同时力求严谨,以体现实事求是和一丝不苟的科学研究精神。不过疏忽和遗漏在所难免,有不当的地方还请各位读者多多包涵,并联系笔者进行修正。愿君阅读愉快!
这是一个看脸的世界!自拍,我们要艺术美颜;出门,我么要靓丽美妆。上班,我们要刷脸签到;回家,我们要看脸相亲。 当手机把你的脸变得美若天仙,当考勤机认出你的脸对你表示欢迎,你知道是什么魔力让冷冰冰的机器也变得温情脉脉,让呆呆的设备也变得善解人意吗?今天就让我们走近它们的内心,了解这些故事背后的一项关 键技术: 人脸检测 。 看人先看脸,走在大街上,我们可以毫不费劲地看到所有人的脸:棱角分明的国字脸,娇小可人的瓜子脸,擦肩而过路人甲的脸,迎面走来明星乙的脸,戴着口罩被遮住的脸,斜向上45度仰角自拍的脸。可是,对于我们的计算机和各种终端设备而言,从眼前的画面中把人脸给找出来,并不是一件容易的事情,原因就在于,一千个读者就有一千个哈姆雷特,在你的眼里,人脸是这样的: 而在机器的眼里,人脸是这样的: 你没看错,图像存储在机器中不过就是一个由0和1组成的二进制串!更确切地说,机器看到的是图像上每一个点的颜色值,因此对于机器来说,一张图像就是一个由数排成的阵列。试想一下,如果我把每个点的颜色值都念给你听,你能告诉我对应的这张图像上有没有人脸和人脸在哪里吗?很显然,这并不是一个容易解决的问题。 如果手机没法在自拍照中找到我们脸,那它就像一个失明的化妆师,没法展现出我们最好的一面;如果考勤机没法通过摄像头看到我们的脸,那我们的笑就只是自作多情,它也根本不可能识别出我们到底是谁。人脸检测架起了机器和我们之间沟通的桥梁,使得它能够知道我们的身份(人脸识别),读懂我们的表情(表情识别),和我们一起欢笑(人脸动画),与我们一起互动(人机交互)。人脸检测的开始和基本流程 具体来说,人脸检测的任务就是判断给定的图像上是否存在人脸,如果人脸存在,就给出全部人脸所处的位置及其大小。由于人脸检测在实际应用中的重要意义,早在上世纪70年代就已经有人开始研究,然而受当时落后的技术条件和有限的需求所影响,直到上世纪90年代,人脸检测技术才开始加快向前发展的脚步,在新世纪到来前的最后十年间,涌现出了大量关于人脸检测的研究工作,这时期设计的很多人脸检测器已经有了现代人脸检测技术的影子,例如可变形模板的设计(将人脸按照五官和轮廓划分成多个相互连接的局部块)、神经网络的引入(作为判断输入是否为人脸的 分类模型)等。这些早期的工作主要关注于检测正面的人脸,基于简单的底层特征如物体边缘、图像灰度值等来对图像进行分析,结合关于人脸的先验知识来设计模型和算法(如五官、肤色),并开始引入一些当时已有的的模式识别方法。 虽然早期关于人脸检测的研究工作离实际应用的要求还有很远,但其中进行检测的流程已经和现代的人脸检测方法没有本质区别。给定一张输入图像,要完成人脸检测这个任务,我们通常分成三步来进行: 1. 选择图像上的某个(矩形)区域作为一个观察窗口; 2.在选定的窗口中提取一些 特征对其包含的图像区域进行描述; 3.根据特征描述来 判断这个窗口是不是正好框住了一张人脸。 检测人脸的过程就是不断地执行上面三步,直到遍历所有需要观察的窗口。如果所有的窗口都被判断为不包含人脸,那么就认为所给的图像上不存在人脸,否则就根据判断为包含人脸的窗口来给出人脸所在的位置及其大小。 那么,如何来选择我们要观察的窗口呢?所谓眼见为实,要判断图像上的某个位置是不是一张人脸,必须要观察了这个位置之后才知道,因此,选择的窗口应该覆盖图像上的所有位置。显然,最直接的方式就是让观察的窗口在图像上从左至右、从上往下一步一步地滑动,从图像的左上角滑动到右下角——这就是所谓的滑动窗口范式,你可以将它想象成是福尔摩斯(检测器)在拿着放大镜(观察窗口)仔细观察案发现场(输入图像)每一个角落(滑动)的过程。 别看这种用窗口在图像上进行扫描的方式非常简单粗暴,它的确是一种有效而可靠的窗口选择方法,以至于直到今天,滑动窗口范式仍然被很多人脸检测方法所采用,而非滑动窗口式的检测方法本质上仍然没有摆脱对图像进行密集扫描的过程。 对于观察窗口,还有一个重要的问题就是:窗口应该多大?我们认为一个窗口是一个人脸窗口当且仅当其恰好框住了一张人脸,即窗口的大小和人脸的大小是一致的,窗口基本贴合人脸的外轮廓。 那么问题来了,即使是同一张图像上,人脸的大小不仅不固定,而且可以是任意的,这样怎么才能让观察窗口适应不同大小的人脸呢?一种做法当然是采用多种不同大小的窗口,分别去扫描图像,但是这种做法并不高效。换一个角度来看,其实也可以将图像缩放到不同的大小,然后用相同大小的窗口去扫描——这就是所谓的构造 图像金字塔的方式。图像金字塔这一名字非常生动形象,将缩放成不同大小的图像按照从大到小的顺序依次往上堆叠,正好就组成了一个金字塔的形状。 通过构建图像金字塔,同时允许窗口和人脸的贴合程度在小范围内变动,我们就能够检测到不同位置、不同大小的人脸了。另外需要一提的是,对于人脸而言,我们通常只用正方形的观察窗口,因此就不需要考虑窗口的长宽比问题了。 选好了窗口,我们开始对窗口中的图像区域进行观察,目的是收集证据——真相只有一个,我们要依靠证据来挖掘真相!在处理图像的过程中,这个收集证据的环节我们称之为特征提取,特征就是我们对图像内容的描述。由于机器看到的只是一堆数值,能够处理的也只有数值,因此对于图像所提取的特征具体表示出来就是一个向量,称之为特征向量,其每一维是一个数值,这个数值是根据输入(图像区域)经由某些计算(观察)得到的,例如进行求和、相减、比较大小等。总而言之,特征提取过程就是从原始的输入数据(图像区域颜色值排列组成的矩阵)变换到对应的特征向量的过程,特征向量就是我们后续用来分析和寻找真相的证据。 特征提取之后,就到了决断的时刻:判别当前的窗口是否恰好包含一张人脸。我们将所有的窗口划分为两类,一类是恰好包含人脸的窗口,称之为 人脸窗口,剩下的都归为第二类,称之为 非人脸窗口,而最终判别的过程就是一个对当前观察窗口进行 分类的过程。因为我们的证据是由数值组成的特征向量,所以我们是通过可计算的 数学模型来寻找真相的,用来处理分类问题的数学模型我们通常称之为 分类器,分类器以特征向量作为输入,通过一系列数学计算,以类别作为输出——每个类别会对应到一个数值编码,称之为这个类别对应的 标签, 如将人脸窗口这一类编码为1,而非人脸窗口这一类编码为-1;分类器就是一个将特征向量变换到类别标签的函数。 考虑一个最简单的分类器:将特征向量每一维上的数值相加,如果得到的和超过某个数值,就输出人脸窗口的类别标签1,否则输出非人脸窗口的类别标签-1。记特征向量为 ,分类器为函数f(x),那么有: 这里的t就是前面所说的“某个数值”,其决定了分类器在给定特征向量下的输出结果,我们称其为分类器的参数。不同形式和类型的分类器会有不同的参数,一个分类器可以有一个或者多个参数,参数或者其取值不同则对应到不同的分类器。选定了一个分类器之后,紧接着的一个问题就是:参数该怎么设置?具体到我们正在考虑的情况,就是:t的值该如何选取? 要做出选择,就要有一个目标,在分类问题中,目标当然就是 尽可能正确地进行分类,即分类的准确率尽可能高。然而,尽管我们对目标非常明确,我们也仍然没法给出一个 最优的参数取值,因为我们并不使用机器所采用的二进制语言系统,我们并不懂什么才是对机器最好的。于是我们只有一种选择:把我们的目标告诉机器,举一些例子向其进行解释,然后让机器自己去 学习这个参数,最后我们给机器设计一场考试,测试其是否满足了我们的要求。我们从一些图像上选出一部分人脸和非人脸窗口的样例,用对应的类别标签对其进行 标注,然后将这些样例划分成两个集合,一个集合作为分类器学习所使用的 训练集,另一个集合作为最终考查分类器能力的 测试集,同时我们设定一个目标:希望分类的准确率能够在80%以上。 学习过程开始时,我们先给分类器的参数设定一个初始值,然后让分类器通过训练集中带有“答案”(类别标签)的样例,不断去调整自己参数的取值,以缩小其实际的分类准确率和目标准确率之间的差距。当分类器已经达到了预先设定的目标或者其它停止学习的条件——期末考试的时间是不会因为你没有学好而推迟的,或者分类器觉得自己已经没有办法再调整了,学习过程就停止了,这之后我们可以考查分类器在测试集上的准确率,以此作为我们评判分类器的依据。这一过程中,分类器调整自己参数的方式和分类器的类型、设定的目标等都有关,由于这部分内容超出了本文所讨论的范畴,也并不影响读者对人脸检测方法的理解,因此不再展开进行讲述。 在确定了选择窗口的策略,设计好了提取特征的方式,并学习了一个针对人脸和非人脸窗口的分类器之后,我们就获得了构建一个人脸检测系统所需要的全部关键要素——还有一些小的环节相比之下没有那么重要,这里暂且略去。 由于采用滑动窗口的方式需要在不同大小的图像上的每一个位置进行人脸和非人脸窗口的判别,而对于一张大小仅为480*320的输入图像,窗口总数就已经高达数十万,面对如此庞大的输入规模,如果对单个窗口进行特征提取和分类的速度不够快,就很容易使得整个检测过程产生巨大的时间开销,也确实就因为如此,早期所设计的人脸检测器处理速度都非常慢,一张图像甚至需要耗费数秒才能处理完成——视频的播放速度通常为每秒25帧图像,这给人脸检测投入现实应用带来了严重的障碍。人脸检测技术的突破:VJ人脸检测器及其发展 人脸检测技术的突破发生在2001年,两位杰出的科研工作者Paul Viola和Michael Jones设计了出了一个快速而准确的人脸检测器:在获得相同甚至更好准确度的同时,速度提升了几十上百倍——在当时的硬件条件下达到了每秒处理15张图像的速度,已经接近实时速度25fps(即25帧每秒)。这不仅是人脸检测技术发展的一个里程碑,也标志着计算机视觉领域的研究成果开始具备投入实际应用的能力。为了纪念这一工作,人们将这个人脸检测器用两位科研工作者的名字命名,称之为Viola-Jones人脸检测器,或者简称为VJ人脸检测器。 VJ人脸检测之所以器能够获得成功,极大地提高人脸检测速度,其中有三个关键要素:特征的快速计算方法——积分图,有效的分类器学习方法——AdaBoost,以及高效的分类策略——级联结构的设计。VJ人脸检测器采用Haar特征来描述每个窗口,所谓Haar特征,其实就是在窗口的某个位置取一个矩形的小块,然后将这个矩形小块划分为黑色和白色两部分,并分别对两部分所覆盖的像素点(图像上的每个点称为一个像素)的灰度值求和,最后用白色部分像素点灰度值的和减去黑色部分像素点灰度值的和,得到一个Haar特征的值。 Haar特征反映了局部区域之间的相对明暗关系,能够为人脸和非人脸的区分提供有效的信息,例如眼睛区域比周围的皮肤区域要暗,通过Haar特征就可以将这一特点表示出来。但是由于提取Haar特征时每次都需要计算局部区域内多个像素点灰度值之和,因此在速度上其并不快,为此VJ人脸检测器引入了 积分图来加速Haar特征的提取。 积分图是一张和输入图像一样大的图,但其每个点上不再是存放这个点的灰度值,而是存放从图像左上角到该点所确定的矩形区域内全部点的灰度值之和。 积分图所带来的好处是两方面的,一方面它使得每次计算局部区域像素点的灰度值之和仅需要做4次加减法,与局部区域的大小无关;另一方面它避免了在相同像素点上重复求和,只在最开始计算一次——相邻的窗口有很大的重叠部分,对应的Haar特征也会重叠,如果每次都重新计算像素点的灰度值之和,则重叠部分的计算是重复的。积分图极大地加速了Haar特征的提取,向快速的检测器迈出了第一步。 除了特征提取,分类过程的速度对于检测的速度也至关重要。分类的速度取决于分类器的复杂程度,也即从特征向量变换到类别标签的计算过程的复杂程度。复杂的分类器往往具有更强的分类能力,能够获得更好的分类准确度,但是分类时的计算代价比较高,而简单的分类器虽然计算代价小,但是分类准确度也较低。那么有没有兼顾计算代价和分类准确度两方面的办法呢?当然有,这就是AdaBoost方法。希望计算代价小,所以只用简单的分类器,但是又希望分类准确度高,于是把多个简单的分类器组合起来——聚弱为强,将多个弱分类器组合成一个强分类器,这就是AdaBoost方法的核心理念。通过AdaBoost方法来学习分类器,达到了以更小的计算代价换取同样的分类准确度的目的。 造成人脸检测速度慢的根本原因还在于输入规模过大,动辄需要处理几十上百万的窗口,如果这样的输入规模是不可避免的,那么有没有可能在处理的过程中尽快降低输入规模呢?如果能够通过粗略地观察快速排除掉大部分窗口,只剩下少部分窗口需要进行仔细的判别,则总体的时间开销也会极大地降低。从这样的想法出发,VJ人脸检测器采用了一种级联结构来达到逐步降低输入规模的目的。 具体说来,VJ人脸检测器将多个分类器级联在一起,从前往后,分类器的复杂程度和计算代价逐渐增大,对于给定的一个窗口,先由排在最前面也最简单的分类器对其进行分类,如果这个窗口被分为非人脸窗口,那么就不再送到后面的分类器进行分类,直接排除,否则就送到下一级分类器继续进行判别,直到其被排除,或者被所有的分类器都分为人脸窗口。这样设计的好处是显而易见的,每经过一级分类器,下一级分类器所需要判别的窗口就会减少,使得只需要付出非常少的计算代价就能够排除大部分非人脸窗口。从另一个角度来看,这实际上也是根据一个窗口分类的难度动态地调整了分类器的复杂程度,这显然比所有的窗口都用一样的分类器要更加高效。 VJ人脸检测器通过积分图、AdaBoost方法和级联结构取得的巨大成功对后续的人脸检测技术研究产生了深远的影响,大量的科研工作者开始基于VJ人脸检测器进行改进,这些改进也分别覆盖了VJ人脸检测器的三个关键要素。在早期的人脸检测工作中,一般采用MIT-CMU人脸检测数据集作为人脸检测器的测试集,来比较不同的检测器。这个测试集只包含几百张带有人脸的图像,并且人脸主要是清晰且不带遮挡的正面人脸,因而是一个相对简单的测试集,现在几乎已经不再使用。在2010年,美国麻省大学的一个实验室推出了一个新的人脸检测评测数据集:FDDB,这个集合共包含2845张带有人脸的互联网新闻图像,一共标注了5171张人脸,其中的人脸在姿态、表情、光照、清晰度、分辨率、遮挡程度等各个方面都存在非常大的多样性,贴近真实的应用场景,因而是一个非常具有挑战性的测试集。FDDB的推出激发人们在人脸检测任务上的研究热情,极大地促进了人脸检测技术的发展,在此后的几年间,新的人脸检测方法不断涌现,检测器在FDDB上的表现稳步提高。从100个误检时的检测率来看,从最初VJ人脸检测器的30%,发展到现在已经超过了90%——这意味着检测器每检测出50张人脸才会产生一个误检,这其中的进步是非常惊人的,而检测器之间的比拼还在继续。
******************
感谢以上文章的作者!