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

📅  最后修改于: 2021-01-07 06:45:54             🧑  作者: Mango

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

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

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

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

存在各种面部检测和面部识别算法。在这里,我们将学习使用HAAR级联算法的面部检测。

HAAR级联算法的基本概念

HAAR级联是一种机器学习方法,其中从许多正负图像中训练级联函数。正图像是由面部组成的图像,负图像则没有面部。在人脸检测中,图像特征被视为从图片中提取的数字信息,可以将一个图像与另一个图像区分开。

我们将算法的所有功能应用于所有训练图像。开始时,每个图像的权重均相等。它找到了将人脸分为正面和负面的最佳阈值。可能存在错误和错误分类。我们选择错误率最低的特征,这意味着这些特征是对人脸和非人脸图像进行最佳分类的特征。

每个内核的所有可能的大小和位置都用于计算大量功能。

OpenCV中的HAAR级联检测

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

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

为了进行培训,我们需要一组样本。有两种类型的样本:

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

必须手动准备一组阴性样品,而使用opencv_createsamples实用程序创建阳性样品的集合。

负样本

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

正样本

正样本由opencv_createsamples实用程序创建。可以从带有对象的单个图像或从较早的集合创建这些样本。重要的是要记住,在将其提供给所提到的实用程序之前,我们需要大量的正样本数据集,因为它仅应用透视变换。

在这里,我们将讨论检测。 OpenCV已经包含各种针对面部,眼睛,微笑等进行过预训练的分类器。这些XML文件存储在opencv / data / haarcascades /文件夹中。让我们了解以下步骤:

第1步

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

第2步

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

步骤-3

haar-Like特征算法用于查找帧或图像中人脸的位置。人类的所有面部都有一些常见的面部通用属性,例如眼睛区域比邻居的像素暗,鼻子区域比眼睛区域亮。

步骤4

在此步骤中,我们将借助边缘检测,线条检测和中心检测从图像中提取特征。然后提供x,y,w,h的坐标,这将在图片中创建一个矩形框以显示脸部的位置。它可以在检测到面部的所需区域中创建一个矩形框。

使用OpenCV进行人脸识别

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

David HubelTorsten Wiesel表明,我们的大脑具有专门的神经细胞,可以对场景的独特局部特征做出响应,例如线条,边缘角度或运动。我们的大脑将不同的信息源组合成有用的模式。我们看不到视觉是分散的。如果我们用一个简单的词来定义面部识别,“自动面部识别将要从图像中去除那些有意义的特征,并将其放入有用的表示中,然后对它们进行一些分类”。

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

通过计算探针和参考图像的特征向量之间的欧式距离来实现人脸识别。这种方法就其性质而言在照明变化方面是有效的,但是它具有很大的缺点。制造商的正确注册非常困难。

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

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

它将输入的面部图像与与用户相关的面部图像进行比较,这是需要认证的。这是1×1的比较。

  • 识别或面部识别

它基本上从数据集中比较输入的面部图像,以找到与该输入面部匹配的用户。这是1xN的比较。

有多种类型的面部识别算法,例如:

  • 特征脸(1991)
  • 本地二进制图案直方图(LBPH)(1996)
  • Fisherfaces(1997)
  • 尺度不变特征变换(SIFT)(1999)
  • 加快健壮功能(SURF)(2006)

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

LBPH介绍

局部二进制图案直方图算法是一种简单的方法,可以标记图像的像素并以每个像素的邻域为阈值。换句话说,LBPH通过将每个像素与其相邻像素进行比较来总结图像中的局部结构,并将结果转换为二进制数。它于1994年(LBP)首次定义,从那时起,它被认为是一种强大的纹理分类算法。

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

在上图中,以一个像素为中心并以其邻居为阈值。如果中心像素的强度大于等于它的相邻像素,则用1表示,否则用0表示。

让我们了解一下算法的步骤:

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

  • 半径:代表中心像素周围的半径。通常设置为1。用于构建圆形局部二进制模式。
  • 邻居:构建圆形二进制图案的采样点数。
  • 网格X:水平方向上的像元数。单元越多,网格越细,结果特征向量的维数就越高。
  • 网格Y:垂直方向的像元数。单元越多,网格越细,结果特征向量的维数就越高。

注意:上面的参数有些混乱。在进一步的步骤中将更加清楚。

2.训练算法:第一步是训练算法。它需要一个包含我们要识别的人的面部图像的数据集。每个图像都应提供一个唯一的ID(可以是人的数字或姓名)。然后,算法使用此信息来识别输入图像并为您提供输出。特定人物的图像必须具有相同的ID。让我们在下一步中了解LBPH的计算。

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

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

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

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

  • 我们有一个灰度图像;每个直方图(来自每个网格)将仅包含256个位置,代表每个像素强度的出现。
  • 需要通过串联每个直方图来创建新的更大的直方图。

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

  • 有多种方法可以比较直方图(计算两个直方图之间的距离),例如:欧几里得距离,卡方,绝对值等。我们可以根据以下公式使用欧几里得距离:

  • 该算法将从具有最直方图的图像返回ID作为输出。该算法还应该返回计算出的距离,这可以称为置信度测量。如果置信度低于阈值,则表示该算法已成功识别出脸部。

我们已经讨论了面部检测和面部识别。类似于haar的级联算法用于面部检测。存在多种用于面部识别的算法,但是LBPH是其中的一种简单且流行的算法。它通常着重于图像中的局部特征。