OpenCV 人脸识别和人脸检测

OpenCV 人脸识别和人脸检测

人脸识别是一种通过数字图像或视频帧识别或验证人脸的技术。人类可以很快地识别出人脸,不费太多努力。这对我们来说是一项轻松的任务,但对计算机来说是一项困难的任务。诸如低分辨率、遮挡、光照变化等各种复杂因素会极大地影响计算机识别人脸的准确性。首先,了解人脸检测和人脸识别之间的区别是必要的。

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

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

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

HAAR级联算法的基本概念

HAAR级联是一种机器学习方法,其中从许多正负图像中训练出级联函数。正图像是包含人脸的图像,而负图像则没有人脸。在人脸检测中,图像特征被视为从图片中提取出的用于区分一张图像与另一张图像的数字信息。

我们在所有训练图像上应用算法的每个特征。每个图像在开始时被赋予相等的权重。它找到将人脸分类为正和负的最佳阈值。可能会有错误和分类错误。我们选择具有最小错误率的特征,这意味着这些特征最能正确对人脸和非人脸图像进行分类。

使用所有可能大小和位置的内核来计算大量特征。

OpenCV中的HAAR级联检测

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

OpenCV提供了两个应用程序进行级联分类器训练,分别是opencv_haartrainingopencv_traincascade。这两个应用程序使用不同的文件格式存储分类器。

对于训练,我们需要一组样本。有两种类型的样本:

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

负样本必须手动准备,而正样本的集合是使用opencv_createsamples实用程序创建的。

负样本

负样本来自任意图像。负样本添加到文本文件中。文件的每一行都包含一个负样本的图像文件名(相对于描述文件目录)。此文件必须手动创建。定义的图像大小可能不同。

正样本

正样本是通过opencv_createsamples工具创建的。这些样本可以从带有物体的单个图像创建,也可以从之前的集合中创建。重要的是要记住,在将其提供给上述工具之前,我们需要一个大的正样本数据集,因为它只应用透视变换。

OpenCV 人脸识别和人脸检测

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

步骤 -1

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

步骤 -2

将图像转换为灰度图后,我们可以进行图像操作,例如重新调整大小、裁剪、模糊和锐化。下一步是图像分割;识别单个图像中的多个对象,使分类器能够快速检测出图像中的对象和人脸。

步骤 -3

使用haar-Like特征算法来找到帧或图像中人脸的位置。所有的人脸都有一些普遍的特征,比如眼睛区域的像素比它的邻居要暗,鼻子区域比眼睛区域更亮。

步骤 -4

在这一步中,我们通过边缘检测、线检测和中心检测从图像中提取特征。然后提供x、y、w、h的坐标,以在图片中创建一个矩形框,显示人脸的位置。它可以在检测到人脸的区域创建一个矩形框。

OpenCV 人脸识别和人脸检测

使用OpenCV进行人脸识别

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

大卫·休贝尔托尔斯滕·威塞尔 表明我们的大脑具有对场景独特局部特征(线条,边角,运动等)做出反应的特殊神经细胞。我们的大脑将不同信息源结合起来形成有用的模式;我们不会将视觉信息视为零散的。如果用简单的话来定义人脸识别,“自动人脸识别是从图像中提取有意义的特征并将其放入有用的表示中,然后对其进行一些分类。”

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

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

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

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

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

  • 鉴别或人脸识别

它基本上将数据集中的输入面部图像与匹配该输入面部的用户进行比较。这是一种1对N的比较。

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

  • 特征脸(1991年)
  • 局部二进制模式直方图(LBPH)(1996年)
  • 费舍尔脸(1997年)
  • 尺度不变特征变换(SIFT)(1999年)
  • 加速稳健特征(SURF)(2006年)

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

LBPH简介

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

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

OpenCV 人脸识别和人脸检测

在上面的图像中,以一个像素为中心,对其邻居进行阈值分割。如果中心像素的强度大于等于其邻居,则用1表示,否则用0表示。

让我们了解算法的步骤:

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

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

注意:上述参数可能有些令人困惑。进一步的步骤将更加清晰。

2. 训练算法: 第一步是训练算法。需要一个包含要识别的人脸图像的数据集。每个图像应该带有一个唯一的ID(可以是人的编号或姓名)。然后算法使用这些信息来识别输入图像并给出输出。一个特定的人的图像必须具有相同的ID。在下一步中了解LBPH的计算过程。

3. 使用LBP操作: 在这一步中,使用LBP计算来创建一幅描述原始图像的中间图像,通过突出显示面部特征。参数 半径邻居 在滑动窗口的概念中使用。

OpenCV 人脸识别和人脸检测

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

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

OpenCV 人脸识别和人脸检测

4. 从图像中提取直方图: 在上一步骤中生成了图像,我们可以使用 Grid XGrid Y 参数将图像分成多个网格,考虑以下图像:
OpenCV 人脸识别和人脸检测

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

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

  • 有各种方法来比较直方图(计算两个直方图之间的距离),例如: 欧氏距离、卡方、绝对值等 。我们可以使用基于以下公式的欧氏距离:

OpenCV 人脸识别和人脸检测

  • 算法将从与最接近直方图的图像中返回ID作为输出。算法还应返回可以称为 置信度 的计算距离。如果置信度低于阈值,则表示算法成功识别了人脸。

我们已经讨论了人脸检测和人脸识别。haar-like级联算法用于人脸检测。有各种各样用于人脸识别的算法,但LBPH是其中一种简单且流行的算法。它通常关注图像中的局部特征。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程