OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
级联分类器

上一个教程: 光流
下一个教程: 级联分类器训练

原始作者Ana Huamán
兼容性OpenCV >= 3.0

目标

在本教程中,

  • 我们将学习 Haar 级联对象检测的工作原理。
  • 我们将了解使用基于 Haar 特征的级联分类器进行人脸检测和眼睛检测的基础知识。
  • 我们将使用 cv::CascadeClassifier 类来检测视频流中的对象。具体来说,我们将使用以下函数:

理论

基于 Haar 特征的级联分类器进行对象检测是由 Paul Viola 和 Michael Jones 在其 2001 年的论文《使用增强级联简单特征的快速对象检测》("Rapid Object Detection using a Boosted Cascade of Simple Features")中提出的一种有效的对象检测方法。它是一种基于机器学习的方法,其中级联函数通过大量正向图像和负向图像进行训练。然后将其用于检测其他图像中的对象。

这里我们将进行人脸检测。最初,该算法需要大量正向图像(人脸图像)和负向图像(无人脸图像)来训练分类器。然后我们需要从中提取特征。为此,使用了如下图所示的 Haar 特征。它们就像我们的卷积核。每个特征是一个通过从黑色矩形下像素和中减去白色矩形下像素和而获得的单个值。

image

现在,每个核的所有可能尺寸和位置都被用来计算大量的特征。(想象一下这需要多少计算量?即使一个 24x24 的窗口也会产生超过 160000 个特征)。对于每个特征计算,我们需要找到白色和黑色矩形下的像素和。为了解决这个问题,他们引入了积分图。无论你的图像有多大,它都能将给定像素的计算简化为仅涉及四个像素的操作。很棒,不是吗?它让事情变得超快。

但在我们计算的所有这些特征中,大多数都是不相关的。例如,考虑下图。顶行显示了两个好的特征。第一个选定的特征似乎侧重于眼睛区域通常比鼻子和脸颊区域更暗的特性。第二个选定的特征依赖于眼睛比鼻梁更暗的特性。但同样的窗口应用于脸颊或任何其他地方则是不相关的。那么我们如何从 160000 多个特征中选择最好的特征呢?这可以通过 Adaboost 实现。

image

为此,我们将每一个特征应用于所有训练图像。对于每个特征,它会找到最佳阈值,将人脸分类为正向和负向。显然,会存在错误或错误分类。我们选择错误率最小的特征,这意味着它们是最能准确分类人脸和非人脸图像的特征。(这个过程不像这般简单。开始时,每张图像都被赋予相同的权重。每次分类后,错误分类图像的权重会增加。然后重复相同的过程。计算新的错误率。同时计算新的权重。这个过程一直持续到达到所需的准确率或错误率,或者找到所需的特征数量)。

最终的分类器是这些弱分类器的加权和。之所以称之为弱分类器,是因为它单独无法分类图像,但与其他分类器一起形成一个强分类器。论文指出,即使 200 个特征也能提供 95% 准确率的检测。他们的最终设置包含大约 6000 个特征。(想象一下从 160000 多个特征减少到 6000 个特征。这是一个巨大的提升)。

现在你拿一张图像。取每一个 24x24 的窗口。对它应用 6000 个特征。检查它是否是人脸。哇……这难道不是有点低效和耗时吗?是的,确实如此。作者对此有一个很好的解决方案。

在一张图像中,大部分区域是非人脸区域。因此,更好的方法是使用一种简单的方法来检查一个窗口是否是非人脸区域。如果不是,则立即将其丢弃,不再对其进行处理。相反,专注于可能存在人脸的区域。这样,我们就可以花更多时间检查可能的人脸区域。

为此,他们引入了级联分类器的概念。特征不是一次性将所有 6000 个特征应用于一个窗口,而是被分组到不同的分类器阶段并逐个应用。(通常前几个阶段会包含极少的特征)。如果一个窗口在第一阶段失败,就丢弃它。我们不再考虑它上面的剩余特征。如果它通过,则应用第二阶段的特征并继续这个过程。通过所有阶段的窗口就是一个人脸区域。这个计划如何!

作者的检测器包含 6000 多个特征,分为 38 个阶段,前五个阶段分别包含 1、10、25、25 和 50 个特征。(上图中所示的两个特征实际上是从 Adaboost 中获得的最佳两个特征)。根据作者的说法,平均每个子窗口只评估 6000 多个特征中的 10 个。

这就是 Viola-Jones 人脸检测工作原理的简单直观解释。有关更多详细信息,请阅读该论文或查阅“附加资源”部分中的参考文献。

OpenCV 中的 Haar 级联检测

OpenCV 提供了一种训练方法(参见 级联分类器训练)或预训练模型,可以使用 cv::CascadeClassifier::load 方法读取。预训练模型位于 OpenCV 安装的 data 文件夹中,或可以在 这里 找到。

以下代码示例将使用预训练的 Haar 级联模型来检测图像中的人脸和眼睛。首先,创建一个 cv::CascadeClassifier 并使用 cv::CascadeClassifier::load 方法加载必要的 XML 文件。之后,使用 cv::CascadeClassifier::detectMultiScale 方法完成检测,该方法返回检测到的人脸或眼睛的边界矩形。

结果

  1. 这是运行上述代码并使用内置网络摄像头视频流作为输入的结果

请确保程序能够找到文件 haarcascade_frontalface_alt.xmlhaarcascade_eye_tree_eyeglasses.xml 的路径。它们位于 opencv/data/haarcascades 中。

  1. 这是使用文件 lbpcascade_frontalface.xml (LBP 训练) 进行人脸检测的结果。对于眼睛,我们仍沿用教程中使用的文件。

附加资源

  1. Paul Viola 和 Michael J. Jones. 鲁棒的实时人脸检测. International Journal of Computer Vision, 57(2):137–154, 2004. [289]
  2. Rainer Lienhart 和 Jochen Maydt. 用于快速对象检测的扩展 Haar-like 特征集. In Image Processing. 2002. Proceedings. 2002 International Conference on, volume 1, pages I–900. IEEE, 2002. [170]
  3. 关于 人脸检测与跟踪 的视频讲座
  4. Adam Harvey 关于人脸检测的一次有趣的采访 Adam Harvey
  5. OpenCV 人脸检测:可视化 在 Vimeo 上由 Adam Harvey 提供