【计算机视觉40例】案例29:LBPH人脸识别

发布于:2023-01-22 ⋅ 阅读:(12) ⋅ 点赞:(0) ⋅ 评论:(0)

导读】本文是专栏《计算机视觉40例简介》的第29个案例《LBPH人脸识别》。该专栏简要介绍李立宗主编《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书的40个案例。

目前,该书已经在电子工业出版社出版,大家可以在京东、淘宝、当当等平台购买。

大家可以在公众号“计算机视觉之光”回复关键字【案例29】获取本文案例的源代码及使用的测试图片等资料。

针对本书40个案例的每一个案例,分别录制了介绍视频。如果嫌看文字版麻烦,可以关注公众号“计算机视觉之光”直接观看视频介绍版。

本文简要介绍了本案例的一些基础知识,更详细的理论介绍、代码实现等内容请参考《计算机视觉40例简介》第26章《人脸识别》以获取更详细信息。

人脸识别的第一步,就是要找到一个模型可以用简洁又具有差异性的方式准确反映出每个人脸的特征。然后,采用该方式提取训练集中每个人脸的特征,得到特征集。识别人脸时,先将当前待识别人脸采用与前述相同的方式提取特征,再从已有特征集中找出当前特征的邻近样本,从而得到当前人脸的标签。

具体示意如图1所示。其中:

  1. 图像(a)是待识别人脸
  2. 图像(b)是已知人脸集合。
  3. 图像(c)是图像(a)的特征值。
  4. 图像(d)是图像(b)中各个人脸对应的特征值(特征集)。经过对比可知图像(a)中待识别人脸的特征值88,与图(d)中的特征值90最为接近。据此,可以将待识别人脸(a)识别为特征值90对应的人脸“己”。
  5. 图像(e)是返回值。即,图像(a)识别的结果是人脸“己”。

为了方便理解,我们可以想象在对比时,有一个反向映射过程。例如:

  1. 图像(f)是待识别人脸,由数值88反向映射得到。
  2. 图像(g)是人脸集合,由图像(d)中的特征值反向映射得到。

通过图像(f)和图像(g),我们可以更直观地观察到,图像(g)中第2行第2列是识别的对应结果。该识别结果,是根据图(c)和图(d)的对应关系确立的。

 

图1 人脸识别示意图

当然,为了方便理解,本例中我们假设特征只有一个值。实践中,会根据实际情况,选取更具代表性、更稳定的特征作为比较判断的依据。当然,这也意味着特征值不再是单一值,而是更复杂、长度更长的值。将上述过程一般化,人脸识别流程示意图如图2所示。具体来说:

  1. 通过特征提取模块,分别完成对训练图像和待识别对象的特征提取;
  2. 将上述特征传递给识别模块。通常,将训练特征传递给训练模型,用来训练一个人脸识别模型;然后将待识别对象特征使用训练好的模型完成识别工作。

 

2 人脸识别流程示意图

在OpenCV中,可以将待识别对象、训练图像及对应标签,在不提取特征的情况下,直接传递给识别模块,识别模块通过生成实例模型、训练模型、完成识别等三个步骤实现人脸识别,输出识别结果。具体的人脸识别流程如图3所示。

 

3  OpenCV人脸识别流程示意图

LBPH(Local Binary Patterns Histogram,局部二值模式直方图)所使用的模型基于LBP(Local Binary Pattern,局部二值模式)算法。LBP最早是被作为一种有效的纹理描述算子提出的,由于在表述图像局部纹理特征上效果出众而得到广泛应用。

LBP算法的基本原理是,将像素点A的值与其最邻近的8个像素点的值逐一比较:

      1. 如果A的像素值大于等于其临近点的像素值,则得到0。
      2. 如果A的像素值小于其临近点的像素值,则得到1。

最后,将像素点A与其周围8个像素点比较所得到的0、1值连起来,得到一个8位的二进制序列,将该二进制序列转换为十进制数作为点A的LBP值。

下面以图25-10中左侧3×3区域的中心点(像素值为76的点)为例,说明如何计算该点的LBP值。计算时,以其像素值76作为阈值,对其8邻域像素进行二值化处理,

  1. 将像素值大于等于76的像素点处理为1。例如,其邻域中像素值为128、251、99、213的点,都被处理为1,填入对应的像素点位置上。
  2. 将像素值小于76的像素点处理为0。例如,其邻域中像素值为36、9、11、48的点,都被处理为0,填入对应的像素点位置上。

根据上述计算,可以得到图4中右图所示的二值结果。

 

4  LBP原理示意图

完成二值化以后,任意指定一个开始位置,将得到的二值结果进行序列化,组成一个8位的二进制数。例如,从当前像素点的正上方开始,以顺时针为序得到二进制序列“01011001”。

最后,将二进制序列“01011001”转换为所对应的十进制数“89”,作为当前中心点的像素值,如图5所示。

 

5 中心点的处理结果

对图像逐像素用以上方式进行处理,就得到LBP特征图像。

使用LBP特征图像所构造的直方图被称为LBPH,或称为LBP直方图。需要注意的是,通常情况下,需要将图像进行分区以取得更好的效果。例如,在图6中:

  • 图像(a)、图像(b)是两幅不一样的图像。
  • 图像(c)、图像(d)是图像(a)、图像(b)各自所对应的直方图。从图中可以看到,虽然图像(a)、图像(b)存在着较大差异,但是二者的灰度直方图是一致。也就说,他们在直方图中,都是由“18个像素值为0的像素点、18个像素值为1的像素点”所构成。从二者的直方图的角度来看,二者是一致的。
  • 图像(e)、图像(f)是图像(a)、图像(b)分区后各自所对应的直方图。从图中可以看到,虽然图像(a)、图像(b)都是由“18个像素值为0的像素点、18个像素值为1的像素点”所构成。但是,如果将图像划分为“3×3像素大小”的单元(cell)后,再观察二者的直方图,二者的差异得以体现。具体表现在,图像(a)和图像(b),两幅图像的各个单元(3×3单元格区域)的直方图是不一样的。

 

6  直方图分区与否的比较

在LBPH算法中,通常先通过LBP算法从图像中提取特征,得到LBP特征图像,再将该图像划分为指定大小的子块后,计算每个子块的直方图。最后,得到LBPH特征值。在OpenCV中,通常将LBP特征图划分为8行8列共64个单元后,分别计算每个单元直方图,最后将这些直方图连接作为最终的LBPH值。

从上面的分析可知,LBP算子是灰度不变的,但却不是旋转不变的。当图像旋转后,会得到不同的LBP值。通过一定的处理,可以让LBP实现旋转不变性。例如,在图7中:

  • 第1列的原始图像中,中心位置的像素点76周围像素点的值都是“36、251、9、99、213、11、48、128”这些值。但是,其周围像素点的分布是不一样的,可以理解从第2行开始的每幅图像都是通过对第1行的图像旋转得到的。简单来说,图像旋转时将所有的像素按照顺时针方向移动一个位置。
  • 第2列“LBP值”,是分别以中心像素点76作为阈值,得到的各个图像所对应的LBP值。
  • 第3列“顶端排序”,是从第2列LBP值的正上方开始,采用顺时针方向,将所有值连接得到的结果。此时,可以看到,虽然每一行图像的中心像素点76周围的像素点都是“36、251、9、99、213、11、48、128”这些像素点。但是,得到的从顶端开始排序的LBP值并不一致。也就是说,在图像发生旋转后,LBP值也发生了变化。
  • 第4列是将第2列LBP值按照从不同的开始位置构建的8个特征值中的最小值。也就是说,针对每一行中的第2列的LBP值,分别从其“正上方、右上角、正右方、右下角、正下方、左下角、正左方、左上角”八个位置作为起始位置,构建8个不同的LBP值,然后取所有这些值的最小值。例如,针对第1行的图像,从不同位置作为起始值,构建的8个特征值分别为“01011001(正上方开始)、10110010(右上角开始)、01100101(正右方开始)、11001010(右下角开始)、10010101(正下方开始)、00101011(左下角开始)、01010110(正左方开始)、10101100(左上角开始)”,得到的最小值是“00101011”。针对,第2行到第8行图像,我们采用同样的操作,计算最小值。以此类推,计算每一行图像对应的LBP最小值。结果发现,他们的最小值是相同的,都是“00101011”。也就是说,无论图像如何旋转,都会得到同一个最小值。实际上,该最小值是所有可能旋转状态中的最小值。因此,如果将该最小值作为LBP特征值,则实现了旋转不变性。

 

7  旋转不变性

从上面的介绍可以看到,LBP特征与Haar特征很相似,都是图像的灰度变化特征。

在《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书中,从算法原理、实现流程等角度系统深入地介绍了该案例的理论基础和实现过程,并对具体的代码实现进行了细致的介绍与解释。欢迎大家阅读第26章《人脸识别》获取详细内容。

《计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测、手势识别、隐身术、以图搜图、车牌识别、图像加密、指纹识别等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面的案例(表情识别、驾驶员疲劳监测、识别性别与年龄等)。