使用LBPH算法理解人脸识别

介绍

**LBPH(Local Binary Pattern Histogram,局部二进制模式直方图)**是一种人脸识别算法,用于识别人脸。它以其性能以及如何能够从正面和侧面识别人脸而闻名。

在开始了解 LBPH 算法之前,让我们先了解一下图像和像素的基础知识,以便在我们开始有关人脸识别的内容之前,了解图像是如何表示的。

因此,让我们开始了解图像和像素。

图像和像素

所有图像都以矩阵格式表示,如你在此处所见,由行和列组成。图像的基本组成部分是像素。图像由一组像素组成。每一个都是小方格。通过将它们并排放置,我们可以形成完整的图像。单个像素被认为是图像中最少可能的信息。对于每张图像,像素值的范围在 0 到 255 之间。

此图像宽 32 像素,高 32 像素。

而当我们将 32 乘以 32 时,结果是 1024,也就是图像中的总像素数。每个像素由三个值组成:R、G、B,分别是红、绿、蓝的基本颜色。

这三种基本颜色的组合将在图像中创建所有这些颜色,因此我们得出结论,单个像素具有三个通道,每个基本颜色一个通道。

由于现在我们对图像和像素有了一些了解,现在就更容易理解 LBPH 算法了。

LBPH(局部二进制模式直方图)

让我们从分析表示图像片段的矩阵开始。正如你之前了解到的,图像以这些格式表示。在这个例子中,我们有三行三列,像素总数为九。让我们在这里选择中心像素,值为 8,并应用一个条件。

如果该值大于或等于 8,则结果为 '1',否则,如果该值小于 8,则结果为零。使用此条件后,矩阵现在看起来像这样。

这个算法的基本计算就是应用这个条件,选择矩阵的中心元素。现在我们需要生成一个二进制值。二进制值 = 11100010 。算法将开始应用从左上角元素到第 2 行的 1 元素的条件,就像它正在制作一个这样的圆圈。

将二进制值转换为十进制值后,我们得到**十进制值 = 226。**它表示中心值周围的所有这些像素等于 226。

当涉及到亮斑时,该算法是稳健的。如果将手电筒放在图像上,像素值会增加。值越高,图像越亮,值越低,图像越暗。

由于这个原因,该算法在明暗图像上都有很好的效果,因为当图像变亮或变暗时,这里的邻域内的所有像素都会发生变化。将光放在图像上后,矩阵将如下所示。应用上述条件后,我们将得到与上述相同的二进制值,即11100010

让我们在这里考虑另一个图像。为了更好地理解算法将如何识别人脸。

我们这里有一张脸的图像,算法将做的是创建几个正方形。

例如,这里的方格不只代表一个像素,而是设置了三行四列的多个像素。三乘四等于这些方格中总共十二个像素,每个方格都是十二个像素。然后我们将该条件应用于每一个。考虑中心像素。

下一步是创建直方图,这是一个统计概念,将计算每种颜色在每个方格中出现的次数。这是直方图的表示。

例如,如果值 110 出现 50 次,则将创建此大小等于 50 的条形,如果 201 出现 110 次,则将在此直方图中创建此大小等于 100 的另一个条形。

通过对直方图的比较,算法将能够识别图像的边缘和角。例如,在第一个方格中,我们没有关于人脸的信息。因此直方图将不同于另一个具有人脸边缘的方格。

总之,算法知道哪些直方图代表边界,哪些直方图代表人的主要特征,比如眼睛的颜色、嘴巴的形状等等。

所以这就是这个算法的基本理论,它基于直方图的创建和比较。

现在让我们开始编码部分

注意:如果你在导入 cv2 库时遇到错误,例如“No module named 'cv2.cv2”。然后你就可以在 google colab 中编写代码了。我已经在 Google Colab 中编写了这段代码。

我将使用 yaleface 数据集

1. 导入库

import os

import cv2

import zipfile

import numpy as np

from google.colab.patches import cv2_imshow

2. 数据收集

path = "/content/drive/MyDrive/Datasets/yalefaces.zip"
zip_obj = zipfile.ZipFile(file = path,mode='r')
zip_obj.extractall('./')
zip_obj.close()

3. 数据清洗

在向模型提供数据之前,这些图像是 .gif 格式,因此我们需要将它们转换为 ndarray,因此我们需要使用以下代码

from PIL import Image

def get_image_data() :
                  paths = [os.path.join("/content/yalefaces/train",f)for f in os.listdir(path="/content/yalefaces/train")]
                  faces = []
                  ids = []
                  #faces will contain the px of the images
                  #path will contain the path of the images
                  for path in paths :
                      image = Image.open(path).convert('L')
                      image_np = np.array(image,'uint8')
                      id = int(os.path.split(path)[1].split(".")[0].replace("subject"," "))
                      ids.append(id)
                      faces.append(image_np)
                    
                    return np.array(ids),faces
ids , faces = get_image_data()

4. 模型训练

lbph_classifier = cv2.face.LBPHFaceRecognizer_create()
lbph_classifier.train(faces,ids)

#Below line will store the histograms for each one of the iamges
lbph_classifier.write('lbph_classifier.yml')

5. 识别人脸

lbph_face_classifier = cv2.face.LBPHFaceRecognizer_create()
lbph_face_classifier.read("/content/lbph_classifier.yml")

#Now we will check the performance of model 

test_image = "/content/yalefaces/test/subject03.leftlight.gif"
image = Image.open(test_image).convert('L')
image_np = np.array(image,'uint8')

#Before giving the image to the model lets check it first
cv2_imshow(image_np)
predictions = lbph_face_classifier.predict(image_np)
print(predictions)

expected_output = int(os.path.split(test_image)[1].split('.')[0].replace("subject"," "))
print(expected_output)
3<-That's our output

这是我们将要测试的图像

第一个参数给出检测到的人脸,第二个参数给出置信度。这是我们从 print(predictions) 得到的输出

cv2.putText(image_np, 'Pred.' +str(predictions[0]),(10,30),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,0))
cv2.putText(image_np, 'Expec.' +str(expected_output),(10,50),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,0)
)
cv2_imshow(image_np)

最后结果

结论

在本文中,我们介绍了以下内容:

  • 什么是LBPH算法

  • LBPH算法如何识别人脸并进行计算

  • 理解代码如何使用LBPH算法识别人脸

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

猜你喜欢

转载自blog.csdn.net/woshicver/article/details/120258917