今天我将给大家带来人
脸
检测的分享。
这次的分享是人
脸
检测的上半部分的分享。
这次分享的主要内容
总共包含三个模块:
第一模块是基本问题。 在这个分享中, 我们将给大家对人脸检测的基本流程以及其中的一些关键技术做一个介绍。
第二模块是传统方法的介绍。 我们选择的传统方法是以手动设计特征以及手动选择S VM、Adaboost 这样的一些分类器的策略。 其中 DPM之类的方法在此不做过多的介绍。
第三模块里我们对我们所选择的传统的方法做一个总结。 主要是从速度和精度这两个方向进行一个总结。
下面开始第一模块, 检测流程和关键技术。 我们首先看一张图:
这是人脸检测的一个典型的应用场景。
我们可以看到这个图有如下几个特点:
首先,这个图它包含了非常多的人脸, 总共包含了几十个人 脸 。
其次,这个图包含 的 人脸的尺度有比较大的变化。 从离摄像头较近的比较大的人脸到离摄像头比较远的人脸, 从正面的人脸到侧面的人脸。 这个图中的人脸, 有 尺度以及角度这样的多样性。
那人 脸 检测的流程是什么样 ? 主要包含三个步骤:
第一个步骤,就是图像块的选择, 也就是说我们要从源头中选择一个图像块, 然后我们检测这个图像块是否包含人脸。
第二步骤就是要提取特征进行描述。提取 特征 必须要能够区分人脸和非人 脸 的图像。
第三个步骤就是对我们第二步骤提取的特征, 使用一个比较 鲁棒 的分类器来进行判断。
所以人脸检测问题实际上它要解决的就是三个问题。
第一个问题,如何选择图 像 块?
这一直是人 脸 检测中最最重要的一个步骤。 当我们选择好一个图像块之后, 我们就可以对这个图像 块 去进行特征的提取了。
在传统方法中, 图像 块 的选择主要是利用滑动窗口的方法, 也就是说我们选择一个滑动窗口, 对原始的图像中进行逐个像素的扫描, 也就是一个密集检测的过程。 然后我们提取到了非常非常多的窗口, 这就是我们候选的人脸选择窗口。 当然这个窗口的选择它必须有一定的策略。 因为在图像之中人脸是有大小的, 也就是 多 尺度 的问题, 所以我们选择的窗口要想覆盖到不同大 小 的人脸, 我们必须进行一个多 尺度 的窗口的设计。
一个常见的方法, 也就是在图像领域中非常非常经典的一个思想,就是 图像 金字塔。 我们可以利用金字塔的多尺度来对我们的滑动窗口进行 选择。
第二个问题就是如何提取这个特征, 如何提取到一个非常鲁棒的能够区分人脸图像和非人脸图像的特征?
这就是一个传统的鲁棒特征的设计问题。在图像处理的发展过程中,已经出现了非常多的经典的图像描述子,
包
括
LBP,HoG
等
,这些都是经过实际验证非常鲁棒的一些特征。传统的方法就是依赖于这些特征以及这些特征的改进。
第三个问题就是我们如何判断它是否为人脸 ?
当然这就是可以利用非常非常多的分类器来进行判断。所以 如何判断 人脸 ,实际 也就是我们分类器的选择问题。
可以说只要解决了在选择图像块的过程中的一个计算量的问题, 解决了一个鲁棒的特征, 以及解决 了 分类器的选择, 就解决了人 脸 检测的问题。
下面我们介绍一个比较具有代表性的传统方法 的 思路。
传统方法提取特征, 它有几个方向:
首先,利用先验知识, 包括:
1)几何位置。 也就是说人脸的图像中的一些子区域, 包括眼睛鼻子嘴巴等, 它们的几何位置是有一些先验知识的。 所以我们可以通过检测这些局部的图像块的存在, 来判断我们这个图像是不是一个人脸图像。
2) 肤色 模型。 通过对我们不同肤色人种建立一个 肤色 模型。 我们可以做一个简单的颜色分类器, 这是最开始的利用这些先验知识的 人脸 检测方法。
其次,随后我们出现了更鲁棒的特征, 这个 更鲁棒 的特征就包括了 LBP纹理描述子 , Haar描述子 以及 HoG 梯度描述 子, 这些特征相对于先验知识来说, 会更加的鲁棒 , 对人 脸 的各种姿态光照会更加 鲁棒 。
再就是分类器的选择。 在传统的方法中, 分类器就包含了S VM、Adaboost 等等一系列比较经典的分类器。
下面我们介绍一下 opencv 里面的一个人脸检测算法, 叫做 VJ 算法。 这是传统的人 脸 检测方法中非常非常具有代表性的一个方法, 它也是最开始的基于深度学习的人脸检测方法的一个启发。
它的基本流程是这样的:
1)利用 Haar 等特征来描述图像区域的共有的属性。 也就是说 Haar 特征就是一个局部 图像块 的特征抽象。
2)建立积分图像。 建立 积分图像的动机就是为了快速获取几种不同的矩形特征, 这是为了解决前面的计算量的问题。 因为对于一张非常大的人脸, 如果我们密集地进行 滑窗的话, 会涉及到大量的图像特征的抽取。 如果我们不进行一个有效的策略的话, 这个计算量是非常之大的。
3)串接不同区域的几何特征。 前面我们虽然利用 Haar 特征提取 了 每一个图像化的特征, 但是这些特征是图像的一个局部区域块, 它并不能完整地描述一个图像。 所以我们要把这些几何特征, 把 不同大小不同尺寸的一个窗口的几何特征进行串接, 从而能更好地描述这样一个图像。 这解决的也是特征的问题。
4) 利用 Adaboost 算法来进行特征的选择与训练。 前面我们选择了非常非常多的特征, 但是其中只有某些特征是对人脸有效的一些特征, 所以我们要利用 Adaboost 算法来进行特征的选择。 这就是 VJ 算法的一个核心的流程。
下面我们对 VJ 算法进行一个比较详细的讲述。
首先, Haar 特征。 什么是 Haar 特征? 所谓 Haar 特征就是我们取一个矩形的小块, 把这个图像块划分成黑色和白色两部分区域, 然后我们分别对这个黑色和白色这两部分区域的灰度值进行求和。 求和之后, 我们对这两部分的灰度值的均值去做一个相减的操作, 就得到了 Haar 特征。
我们看上面的这张图。
这张图展示了四种不同的类型的矩形区域,
我们都是求取的白色区域
和
黑色区域的一个灰度的差值,
它代表什么?
它代表的就是一个局部区域的相对明暗关系,
这就是
Haar
特征。
另外还有很多的其他的一些常用于 人脸检测和识别的特征, 包括 L BP特征、 Hog 特征以及 Surf 特征 , 它们本质上也是反映局部区域的明暗关系。 因为我们人脸图像本身就有明暗关系, 所以 Haar 特征是一个非常有效的传统的特征。
有了我们的特征之后, 我们如何高效率的计算我们这样的一个海量的窗口里面的特征, 假如在我们没有一个比较高效的策略的前提下, 前面我们使用的是滑窗的方法, 我们通过 滑窗 逐行的扫描我们的图像, 就会产生海量的区域。 这个量是一个什么样的量级呢? 我们可以看到,当我们使用一个 16×16的窗口去扫描图像的时候, 它就会产生 3万多的特征数量。 当这个窗口增加到了 36×36, 特征数量就从 3万多迅速增长到了80多万。 每一个特征数量 都 意味着计算量, 当我们的图像越大, 我们的这个计算量的增长是非常非常的可观的, 所以我们必须要使用一个非常高效的策略, 能够快速的计算这个特征。
积分图 就是做了这样的一个贡献。 它 只需要遍历一次图像, 就可以求出图像中的所有区域的像素。
下面我们看一下积分图的产生。
如上图,左边是一张普通的图,
右边是
它
的积分图。
积分图的产生是这样:
右边的积分图的每一个像素,
它都等于左边的像素对应它左上角的一块矩形区域的值。
所以当我们想得到左边
图像的任意一个子区域的像素和
,
我们只需要用右边的积分图的对应的这个子区域的右下角的像素值减去左上
角
的
像素值
,
就能得到我们左边这个图像任意一个矩形区域的像素和。
而这个像素和就可以用于计算我们
Haar
的特征,
因为我们的
Haar
特征,在前面我们已经讲述过了,
它
无非就是计算了两个矩阵像素和的差,
所以我们利用积分图来计算
Haar
特征是非常之快速的,
这是一个查表的操作。
只需要通过一次的计算操作,
我们建立了这个积分图像之后,
后面我们就可以利用坐标的查表操作,
来得到任意一个区域图像的表征。
最后,当我们已经选好了特征, 同时计算出了很多窗口的 haar 特征之后, 我们就可以利用分类器来对这个特征进行分类。 首先我们要将多个矩形区域的特征组合得到一个区分度更大的特征值, 这也就是整个图像的一个描述。 在得到这样的一个特征 向量 之后, 我们就可以利用 Adaboost 分类器来进行分类。 为什么要选择 Adaboost ? 因为 Adaboost 是一个 级联 的分类器, 包含了非常非常多的弱分类器, 通过这些弱分类器的联合来得到一个性能非常 鲁棒 的分类器, 它的核心思想就是通过多个分类器级联在一起, 从前到后, 分类器的复杂程度和计算代价逐渐增大。 在这个 级联 分类器的前一部分, 分类器的性能是比较简单的, 它的计算代价也比较低, 它可以过滤掉大部分的没有人脸的区域。 随着 分类器往后级联 , 分类器的复杂程度, 也就是它的表征能力会得到提升, 然后计算代价也会增加, 而 它 所要处理的候选的图像区域也减少了。 所以就能得到一个比较鲁棒的检测, 也就是人脸的检测。
可以说级联分类器的思想就是首先通过一些比较弱的分类器迅速过滤掉大部分无效的人脸, 然后一步一步 地对 剩下来的那些图像区域进行更鲁 棒 的检测。 这一方面保证召回率,一方面 保证了 精确度。
最后我们对传统方法做一个简单的总结。 传统方法包括以下几个特点:
首先, 传统 方法 的速度非常快。 前面我们可以看到, VJ 算法 建立 了一个积分图像, 它计算特征是非常快的。
其次, 传统方法的召回率不高。 为什么呢?是因为传统方法它毕竟使用了一个比较固定的 划 窗的策略。 所以对于多尺度的人脸它仍然是受限的, 它的召回率并不是很好, 尤其是对于大角度, 对于姿态比较大的人脸, 它的召回率不高。
最后, 定位精度低。 因为传统的方法, 它没有定位的操作。 也就是说当我们选择了一个图像区域块之后, 我们就利用分类器来对这个图像区域进行分类,分类 它 是人脸或者不是人脸, 但是在这个 分类 之后 没有一个定位的操作, 也就是说如果我们选择了这个图像块, 它本身就是不准的, 本身就有偏差。 传统的像 VJ 这样的方法, 它就无法解决定位的问题。
以上就是我们的传统方法的一个分享。
免费领取技术大咖分享课,加蜂口V信: fengkou-IT
感谢您的阅读,更多精彩请持续关注蜂口微信小程序!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31553577/viewspace-2215201/ ,如需转载,请注明出处,否则将追究法律责任。