![]() |
OpenCV 4.12.0
开源计算机视觉
|
使用基于 Haar 特征的级联分类器进行目标检测是一种有效的方法,由 Paul Viola 和 Michael Jones 在 2001 年的论文“使用增强型简单特征级联的快速目标检测”中提出。这是一种基于机器学习的方法,其中级联函数是从大量的正面和负面图像中训练出来的。然后,它被用于检测其他图像中的对象。
在这里,我们将进行人脸检测。最初,该算法需要大量的正面图像(人脸图像)和负面图像(没有人脸的图像)来训练分类器。然后,我们需要从中提取特征。为此,使用了下图所示的 Haar 特征。它们就像我们的卷积核。每个特征都是通过从白色矩形下的像素总和中减去黑色矩形下的像素总和而获得的单个值。
现在,每个内核的所有可能大小和位置都被用来计算大量的特征。对于每个特征计算,我们需要找到白色和黑色矩形下的像素总和。为了解决这个问题,他们引入了积分图像。它简化了像素总和的计算,无论像素数量有多大,都可以简化为仅涉及四个像素的运算。
但是在我们计算的所有这些特征中,大多数都是不相关的。例如,考虑下面的图像。顶行显示了两个好的特征。选择的第一个特征似乎关注的是眼睛区域通常比鼻子和脸颊区域更暗的特性。选择的第二个特征依赖于眼睛比鼻梁更暗的特性。但是,相同的窗口应用于脸颊或任何其他地方都是无关紧要的。那么,我们如何从 160000 多个特征中选择最佳特征呢?这是通过 Adaboost 实现的。
为此,我们将每个特征都应用于所有训练图像。对于每个特征,它都会找到最佳阈值,将人脸分类为正面和负面。但是很明显,会有错误或误分类。我们选择错误率最低的特征,这意味着它们是最好地对人脸和非人脸图像进行分类的特征。(这个过程并不像这看起来那么简单。每张图像最初都被赋予相同的权重。每次分类后,错误分类的图像的权重都会增加。然后再次执行相同的过程。计算新的错误率。还有新的权重。该过程将继续进行,直到达到所需的准确性或错误率,或找到所需的特征数量)。
最终的分类器是这些弱分类器的加权总和。它被称为弱分类器,因为它本身无法对图像进行分类,但与其他分类器一起可以形成强大的分类器。该论文称,即使 200 个特征也能提供 95% 的检测准确率。他们的最终设置大约有 6000 个特征。(想象一下从 160000 多个特征减少到 6000 个特征。这是一个很大的进步)。
所以现在你拍摄一张图像。取每个 24x24 的窗口。对其应用 6000 个特征。检查它是否是人脸。哇……哇……这不是很低效且耗时吗?是的,确实如此。作者对此有一个很好的解决方案。
在图像中,大部分图像区域是非人脸区域。因此,最好有一种简单的方法来检查窗口是否不是人脸区域。如果不是,则一次性丢弃它。不要再处理它。相反,专注于可能存在人脸的区域。这样,我们可以有更多的时间来检查可能的人脸区域。
为此,他们引入了级联分类器的概念。与其将所有 6000 个特征应用于一个窗口,不如将这些特征分组到不同的分类器阶段并逐个应用。(通常,前几个阶段将包含非常少的特征)。如果窗口未通过第一阶段,则将其丢弃。我们不考虑其上的剩余特征。如果它通过了,则应用第二阶段的特征并继续该过程。通过所有阶段的窗口是人脸区域。计划如何!!!
作者的检测器具有 6000 多个特征,分为 38 个阶段,前五个阶段分别具有 1、10、25、25 和 50 个特征。(上图中的两个特征实际上是从 Adaboost 获得的最佳两个特征)。据作者称,平均而言,每个子窗口评估 6000 多个特征中的 10 个特征。
因此,这是对 Viola-Jones 人脸检测工作原理的简单直观解释。阅读论文以了解更多详细信息。
在这里,我们将处理检测。OpenCV 已经包含许多预先训练的分类器,用于检测人脸、眼睛、微笑等。这些 XML 文件存储在 opencv/data/haarcascades/ 文件夹中。让我们使用 OpenCV 创建一个人脸和眼睛检测器。
我们使用函数:detectMultiScale (image, objects, scaleFactor = 1.1, minNeighbors = 3, flags = 0, minSize = new cv.Size(0, 0), maxSize = new cv.Size(0, 0))
| image | CV_8U 类型的矩阵,其中包含检测到对象的图像。 |
| objects | 矩形向量,其中每个矩形都包含检测到的对象。矩形可能部分位于原始图像之外。 |
| scaleFactor | 指定每个图像比例下图像大小减小的程度的参数。 |
| minNeighbors | 指定每个候选矩形应保留的邻居数的参数。 |
| flags | 与旧级联中 cvHaarDetectObjects 函数中的含义相同的参数。它不适用于新的级联。 |
| minSize | 最小可能的对象大小。小于此大小的对象将被忽略。 |
| maxSize | 最大可能的对象大小。大于此大小的对象将被忽略。如果 maxSize == minSize,则在单个比例上评估模型。 |
使用上面的代码尝试此演示。已准备好名为 haarCascadeDetectionCanvasInput 和 haarCascadeDetectionCanvasOutput 的 Canvas 元素。选择一个图像,然后单击“Try it”以查看结果。您可以在文本框中更改代码以进行更多调查。