使用 OpenCV 进行人脸识别和人脸检测

2025年03月17日 | 阅读 9 分钟

人脸识别是一种从数字图像或视频帧中识别或验证人脸的技术。人类可以毫不费力地快速识别面孔。这对我们来说是一项轻松的任务,但对计算机来说却是一项艰巨的任务。存在各种复杂性,例如低分辨率、遮挡、光照变化等。这些因素极大地影响了计算机有效识别面孔的准确性。首先,有必要了解人脸检测和人脸识别之间的区别。

人脸检测:人脸检测通常被认为是找到图像中的人脸(位置和大小),并可能提取它们以供人脸检测算法使用。

人脸识别:人脸识别算法用于查找图像中唯一描述的特征。面部图像已被提取、裁剪、调整大小,通常转换为灰度。

人脸检测和人脸识别有各种算法。在这里,我们将学习使用 HAAR Cascade 算法进行人脸检测。

HAAR Cascade 算法的基本概念

HAAR Cascade 是一种机器学习方法,其中级联函数从大量正面和负面图像中进行训练。正面图像是包含人脸的图像,负面图像是不包含人脸的图像。在人脸检测中,图像特征被视为从图片中提取的数值信息,这些信息可以区分一张图片与另一张图片。

我们将算法的每个特征应用于所有训练图像。在开始时,每张图像都赋予相等的权重。它找到最佳阈值,该阈值将人脸分类为正面和负面。可能存在错误和误分类。我们选择错误率最低的特征,这意味着这些特征能够最好地区分人脸和非人脸图像。

使用每个核的所有可能尺寸和位置来计算大量特征。

OpenCV 中的 HAAR-Cascade 检测

OpenCV 提供训练器和检测器。我们可以使用 OpenCV 为任何对象(如汽车、飞机和建筑物)训练分类器。级联图像分类器有两个主要状态:第一个是训练,第二个是检测。

OpenCV 提供了两个应用程序来训练级联分类器:opencv_haartrainingopencv_traincascade。这两个应用程序以不同的文件格式存储分类器。

训练需要一组样本。有两种类型的样本

  • 负样本:它与非对象图像相关。
  • 正样本:它是检测对象的相关图像。

必须手动准备一组负样本,而正样本的收集是通过 opencv_createsamples 工具创建的。

负样本

负样本取自任意图像。负样本添加在文本文件中。文件中的每一行都包含负样本的图像文件名(相对于描述文件目录)。必须手动创建此文件。定义的图像可以具有不同的尺寸。

正样本

正样本由 opencv_createsamples 工具创建。这些样本可以从包含对象的单个图像或从先前的集合中创建。重要的是要记住,在将正样本数据集提供给上述工具之前,我们需要一个大型数据集,因为它只会应用透视变换。

Face recognition and Face detection

在这里,我们将讨论检测。OpenCV 已经包含各种预训练的分类器,用于人脸、眼睛、微笑等。这些 XML 文件存储在 opencv/data/haarcascades/ 文件夹中。让我们理解以下步骤

步骤 - 1

首先,我们需要加载必要的 XML 分类器,并将输入图像(或视频)加载为灰度模式。

步骤 -2

将图像转换为灰度后,我们可以进行图像处理,可以根据需要调整图像大小、裁剪、模糊和锐化。下一步是图像分割;识别单个图像中的多个对象,以便分类器可以快速检测图片中的对象和人脸。

步骤 - 3

haar-Like 特征算法用于查找帧或图像中人脸的位置。所有人类面孔都有一些共同的普遍面部特征,例如眼睛区域比其邻近像素暗,而鼻子区域比眼睛区域亮。

步骤 -4

在此步骤中,我们通过边缘检测、线条检测和中心检测提取图像特征。然后提供 x、y、w、h 坐标,这些坐标构成图片中的矩形框以显示人脸的位置。它可以制作一个矩形框在所需区域,在该区域它检测到人脸。

Face recognition and Face detection

使用 OpenCV 进行人脸识别

人脸识别对人类来说是一项简单的任务。成功的人脸识别倾向于有效识别内部特征(眼睛、鼻子、嘴巴)或外部特征(头部、面部、发际线)。这里的问题是人脑如何编码它?

David HubelTorsten Wiesel 表明,我们的大脑中有专门的神经细胞响应场景的独特局部特征,例如线条、边缘角度或运动。我们的大脑将不同来源的信息整合成有用的模式;我们不会将视觉视为分散的。如果我们用简单的词来定义人脸识别,“自动人脸识别就是从图像中提取有意义的特征,并将它们放入有用的表示中,然后对它们进行一些分类”。

人脸识别的基本思想基于人脸的几何特征。它是人脸识别的一种可行且最直观的方法。第一个自动人脸识别系统是在眼睛、耳朵、鼻子位置描述的。这些定位点称为特征向量(点之间的距离)。

人脸识别通过计算探测图像和参考图像的特征向量之间的欧几里得距离来实现。这种方法因其性质而能有效应对光照变化,但有一个相当大的缺点。标记的正确注册非常困难。

人脸识别系统基本可以在两种模式下运行

  • 面部图像的认证或验证 -

它将输入的脸部图像与需要认证的用户的脸部图像进行比较。这是一个 1x1 的比较。

  • 识别或面部识别

它基本上是将输入面部图像与数据集进行比较,以查找与该输入面部匹配的用户。这是一个 1xN 的比较。

有各种类型的人脸识别算法,例如

  • Eigenfaces (1991)
  • 局部二值模式直方图 (LBPH) (1996)
  • Fisherfaces (1997)
  • 尺度不变特征变换 (SIFT) (1999)
  • 加速鲁棒特征 (SURF) (2006)

每种算法都遵循不同的方法来提取图像信息并与输入图像进行匹配。在这里,我们将讨论局部二值模式直方图 (LBPH) 算法,它是最古老且最受欢迎的算法之一。

LBPH 简介

局部二值模式直方图算法是一种简单的方法,通过阈值化每个像素的邻域来标记图像的像素。换句话说,LBPH 通过将每个像素与其邻居进行比较来总结图像中的局部结构,并将结果转换为二进制数字。它最早在 1994 年被定义(LBP),自那时以来,它已被发现是一种强大的纹理分类算法。

该算法通常专注于从图像中提取局部特征。基本思想不是将整个图像视为高维向量;它只关注对象的局部特征。

Face recognition and Face detection

在上图中,以一个像素为中心并根据其邻域进行阈值处理。如果中心像素的强度大于或等于其邻居,则记为 1,否则记为 0。

让我们来理解算法的步骤

1. 选择参数:LBPH 接受四个参数

  • 半径:它表示中心像素周围的半径。通常设置为 1。它用于构建圆形局部二值模式。
  • 邻居:用于构建圆形二值模式的样本点数量。
  • Grid X:水平方向的单元格数量。更多的单元格和更精细的网格代表了生成特征向量的更高维度。
  • Grid Y:垂直方向的单元格数量。更多的单元格和更精细的网格代表了生成特征向量的更高维度。

注意:以上参数有点令人困惑。在后续步骤中会更清楚。

2. 训练算法:第一步是训练算法。它需要一个人脸图像数据集,我们想识别的那个人。应为每张图像提供一个唯一的 ID(可以是数字或人名)。然后算法使用此信息来识别输入图像并给出输出。某个人的图像必须具有相同的 ID。让我们在下一步中理解 LBPH 的计算。

3. 使用 LBP 操作:在此步骤中,使用 LBP 计算来创建一个中间图像,该图像通过突出面部特征以特定方式描述原始图像。半径邻居参数用于滑动窗口的概念。

Face recognition and Face detection

为了更具体地理解,让我们将其分解为几个小步骤

  • 假设输入面部图像是灰度的。
  • 我们可以将该图像的一部分视为一个 3x3 像素的窗口。
  • 我们可以使用包含每个像素强度(0-255)的 3x3 矩阵。
  • 然后,我们需要取矩阵的中心值作为阈值。
  • 该值将用于定义来自 8 个邻居的新值。
  • 对于中心值(阈值)的每个邻居,我们设置一个新的二进制值。对于等于或高于阈值的值,设置为 1,对于低于阈值的值,设置为 0。
  • 现在矩阵将仅包含二进制值(跳过中心值)。我们需要逐行处理矩阵中的每个二进制值,将其转换为新的二进制值(10001101)。还有其他连接二进制值的方法(顺时针方向),但最终结果将是相同的。
  • 我们将这个二进制值转换为十进制值,并将其设置为矩阵的中心值,该中心值是原始图像中的一个像素。
  • 完成 LBP 过程后,我们得到一个新的图像,它更好地表示了原始图像的特征。
Face recognition and Face detection

4. 从图像中提取直方图:在上一步中生成的图像,我们可以使用 Grid XGrid Y 参数将图像划分为多个网格,让我们看下图

Face recognition and Face detection
  • 我们有一个灰度图像,每个直方图(来自每个网格)将只包含 256 个位置,表示每个像素强度的出现次数。
  • 需要通过连接每个直方图来创建一个新的更大的直方图。

5. 执行人脸识别:现在,算法已经训练好了。提取的直方图用于表示训练数据集中的每个图像。对于新图像,我们再次执行这些步骤并创建一个新的直方图。为了找到与给定图像匹配的图像,我们只需匹配两个直方图并返回具有最接近直方图的图像。

  • 有各种方法可以比较直方图(计算两个直方图之间的距离),例如:欧几里得距离、卡方、绝对值等。我们可以根据以下公式使用欧几里得距离
Face recognition and Face detection
  • 算法将从具有最接近直方图的图像中返回 ID 作为输出。算法还应返回计算出的距离,该距离可以称为置信度度量。如果置信度低于阈值,则表示算法已成功识别出人脸。

我们已经讨论了人脸检测和人脸识别。haar like cascade 算法用于人脸检测。人脸识别有各种算法,但 LBPH 是其中一种简单而受欢迎的算法。它通常关注图像中的局部特征。