人脸识别是指程序对输入的人脸图像进行判断,并识别出其对应的人的过程。人脸识别程 序像我们人类一样,“看到”一张人脸后就能够分辨出这个人是家人、朋友还是明星。
当然,要实现人脸识别,首先要判断当前图像内是否出现了人脸,也即人脸检测。只有检 测到图像中出现了人脸,才能根据人脸判断这个人到底是谁。
人脸检测
当我们预测的是离散值时,进行的是“分类”。例如,预测一个孩子能否成为一名优秀的运动员,其实就是看他是被划分为“好苗子”还是“普通孩子”的分类。对于只涉及两个类别的“二分类”任务,我们通常将其中一个类称为“正类”(正样本),另一个类称为“负类”(反类、负样本)。
例如,在人脸检测中,主要任务是构造能够区分包含人脸实例和不包含人脸实例的分类器。这些实例被称为“正类”(包含人脸图像)和“负类”(不包含人脸图像)。
本节介绍分类器的基本构造方法,以及如何调用OpenCV中训练好的分类器实现人脸检测。
基本原理
OpenCV 提供了三种不同的训练好的级联分类器,下面简单介绍其中涉及的一些概念。
- 级联分类器
通常情况下,分类器需要对多个图像特征进行识别。例如,识别一个动物到底是狗(正类)还是其他动物(负类),我们可能需要根据多个条件进行判断,这样比较下来是非常烦琐的。
但是,如果首先就比较它们有几条腿:
- 有“四条腿”的动物被判断为“可能为狗”,并对此范围内的对象继续进行分析和判断。
- 没有“四条腿”的动物直接被否决,即不可能为狗。
这样,仅仅比较腿的数目,根据这个特征就能排除样本集中大量的负类(例如鸡、鸭、鹅等不是狗的其他动物实例)。级联分类器就是基于这种思路,将多个简单的分类器按照一定的顺序级联而成的。
级联分类器的基本原理如图 23-1 所示。
级联分类器的优势是,在开始阶段仅进行非常简单的判断,就能够排除明显不符合要求的实例。在开始阶段被排除的负类,不再参与后续分类,这样能极大地提高后面分类的速度。这有点像我们经常收到的骗子短信,大多数人通常一眼就能识别出这些短信是骗人的,也不可能上当受骗。骗子们随机大量发送大多数人明显不会上当受骗的短信,这种做法虽然看起来非常蠢,但总还是会有人上当。这些短信,在最开始的阶段经过简单的筛选过滤就能够将完全不可能上当的人排除在外。不回复短信的人,是不可能上当的;而回复短信的人,才是目标人群。
这样,骗子轻易地就识别并找到了目标人群,能够更专注地“服务”于他们的“最终目标人群”(不断地进行短信互动),从而有效地避免了与“非目标人群”(不回复短信的人群)发生进一
步的接触而“浪费”时间和精力。
OpenCV 提供了用于训练级联分类器的工具,也提供了训练好的用于人脸定位的级联分类器,都可以作为现成的资源使用。
- Haar级联分类器
OpenCV 提供了已经训练好的 Haar 级联分类器用于人脸定位。Haar 级联分类器的实现,经过了以下漫长的历史:
-
首先,有学者提出了使用 Haar 特征用于人脸检测,但是此时 Haar 特征的运算量超级大,这个方案并不实用。
-
接下来,有学者提出了简化 Haar 特征的方法,让使用 Haar 特征检测人脸的运算变得简单易行,同时提出了使用级联分类器提高分类效率。
-
后来,又有学者提出用于改进 Haar 的类 Haar 方案,为人脸定义了更多特征,进一步提高了人脸检测的效率。
下面用一个简单的例子来叙述上述方案。假设有两幅 4×4 大小的图像,如图 23-2 所示。
针对这两幅图像,我们可以通过简单的计算来判断它们在左右关系这个维度是否具有相关性。
’用两幅图像左侧像素值之和减去右侧像素值之和:
- 针对左图,sum(左侧像素) - sum(右侧像素) = (128+96) - (108+76) = 40
- 针对右图,sum(左侧像素) - sum(右侧像素) = (47+88) - (27+68) = 40
这两幅图像中&#