OpenCV 4.10.0
开源计算机视觉
|
原始作者 | Ana Huamán |
兼容性 | OpenCV >= 3.0 |
在本教程中,
使用基于 Haar 特征的级联分类器进行目标检测是一种有效的方法,由 Paul Viola 和 Michael Jones 在 2001 年的论文“使用简单特征的增强级联进行快速目标检测”中提出。它是一种基于机器学习的方法,其中级联函数从大量的正负样本图像中进行训练。然后用于检测其他图像中的物体。
这里我们将进行人脸检测。最初,该算法需要大量正样本图像(人脸图像)和负样本图像(无脸图像)来训练分类器。然后我们需要从中提取特征。为此,使用下图所示的 Haar 特征。它们就像我们的卷积核。每个特征都是通过从黑色矩形下的像素总和中减去白色矩形下的像素总和而获得的单个值。
现在,每个核的所有可能的尺寸和位置都用于计算大量特征。(想象一下需要多少计算?即使是 24x24 的窗口也会产生超过 160000 个特征)。对于每个特征计算,我们需要找到白色和黑色矩形下像素的总和。为了解决这个问题,他们引入了积分图像。无论你的图像有多大,它都会将给定像素的计算简化为只涉及四个像素的操作。很不错,不是吗?它使事情变得超级快。
但是,在我们计算的所有这些特征中,大多数是无关紧要的。例如,考虑下面的图像。顶行显示了两个好的特征。第一个选择的特征似乎专注于眼睛区域通常比鼻子和脸颊区域更暗的属性。第二个选择的特征依赖于眼睛比鼻梁更暗的属性。但是,相同的窗口应用于脸颊或任何其他地方都是无关紧要的。那么我们如何从 160000 多个特征中选择最佳特征呢?这是通过 Adaboost 实现的。
为此,我们将每个特征应用于所有训练图像。对于每个特征,它都会找到最好的阈值,该阈值将人脸分类为正负样本。显然,会有错误或误分类。我们选择误差率最低的特征,这意味着它们是能够最准确地对人脸和非人脸图像进行分类的特征。(该过程并不像看起来那么简单。最初,每个图像都赋予相同的权重。在每次分类之后,误分类图像的权重都会增加。然后重复相同的过程。计算新的误差率。以及新的权重。该过程持续进行,直到达到所需的精度或误差率,或者找到所需的特征数量)。
最终分类器是这些弱分类器的加权总和。它被称为弱,因为它本身无法对图像进行分类,但与其他分类器一起构成一个强分类器。论文中提到,即使只有 200 个特征也能提供 95% 精度的检测。他们最终的设置大约有 6000 个特征。(想象一下从 160000 多个特征减少到 6000 个特征。这是一个巨大的进步)。
所以现在你拿着一张图像。取每个 24x24 的窗口。将 6000 个特征应用于它。检查它是否是人脸。哇.. 这不是很低效和耗时吗?是的,确实如此。作者对此有一个很好的解决方案。
在图像中,大部分图像都是非人脸区域。所以,最好有一个简单的方法来检查窗口是否不是人脸区域。如果不是,则立即丢弃它,不再处理它。相反,专注于可能存在人脸的区域。这样,我们就可以花更多时间检查可能的人脸区域。
为此,他们引入了 级联分类器 的概念。而不是将所有 6000 个特征应用于一个窗口,这些特征被分组到不同的分类器阶段,并逐个应用。(通常,前几个阶段将包含更少的特征)。如果窗口未通过第一阶段,则丢弃它。我们不考虑它剩下的特征。如果它通过了,则应用第二阶段的特征,并继续该过程。通过所有阶段的窗口都是人脸区域。多么好的计划!
作者的探测器具有 6000 多个特征,有 38 个阶段,前五个阶段分别有 1、10、25、25 和 50 个特征。(上图中的两个特征实际上是从 Adaboost 中获得的最佳两个特征)。据作者所说,平均每个子窗口会评估 6000 多个特征中的 10 个特征。
所以这是一个关于 Viola-Jones 人脸检测如何工作的简单直观的解释。阅读论文以获取更多详细信息,或查看“附加资源”部分中的参考文献。
OpenCV 提供了一种训练方法(见 级联分类器训练)或预训练模型,可以使用 cv::CascadeClassifier::load 方法读取。预训练模型位于 OpenCV 安装中的 data 文件夹中,或者可以在 此处 找到。
以下代码示例将使用预训练的 Haar 级联模型来检测图像中的人脸和眼睛。首先,创建一个 cv::CascadeClassifier,并使用 cv::CascadeClassifier::load 方法加载必要的 XML 文件。之后,使用 cv::CascadeClassifier::detectMultiScale 方法进行检测,该方法会返回检测到的人脸或眼睛的边界矩形。
确保程序能够找到文件 haarcascade_frontalface_alt.xml 和 haarcascade_eye_tree_eyeglasses.xml 的路径。它们位于 opencv/data/haarcascades 中