介绍**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算法识别人脸