LBPH

算法具体流程图:

由于LBPH运用的是局部特征算法,所以对图像明暗度的鲁棒性较好,其次,颜色对人脸识别没有影响,所以导入之后转换为灰度图像,灰度为0-256

计算LBP编码

有经典LBP编码和圆形LBP编码,绕周围一圈八个数,如果比中间的数大,则记为1,反之为0。最后连接之后的01字符串组成一个二进制数,这个二进制数就是这个像素点对应的LBP编码。

均匀化降维

由于灰度有256维,这个矩阵会较为稀疏,所以需要将其降维到更小的维度。此处的实验室将其降维到59维度。实际上,降维的过程就是一个函数映射的过程:将256个二进制数映射到0-59个十进制数上。

具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def getHopCounter(self, num):
'''
计算二进制序列是否只变化两次
:param num: 数字
:return: 01变化次数
'''
binNum = bin(num)
binStr = str(binNum)[2:]
n = len(binStr)
if n < 8:
binStr = "0" * (8 - n) + binStr
n = len(binStr)
counter = 0
for i in range(n):
if i != n - 1:
if binStr[i + 1] != binStr[i]:
counter += 1
else:
if binStr[0] != binStr[i]:
counter += 1
return counter

def createTable(self):
'''
生成均匀对应字典
:return: 均匀LBP特征对应字典
'''
self.table = {}
temp = 1
print
type(temp)
for i in range(256):
if self.getHopCounter(i) <= 2:
self.table[i] = temp
print("tmp",temp)
temp += 1
else:
self.table[i] = 0
return self.table

最后256个二进制数就能够唯一地映射到59个数上。

特征矩阵

特征矩阵就是LBP编码经过降维之后的矩阵。

直方图

实际上是一个统计的结果,即横坐标是59度的灰度,纵坐标是对应的灰度在这张图像中出现的次数,最后归一化,表示的就是这个区域的直方图。

特征向量

将图像分割成一小块一小块之后计算每个小区域的直方图归一化之后,排成一排,就得到了这张图像的特征向量。

人脸识别

  • 可以通过计算每张图片和测试图片的直方图的欧式距离(很慢)——所以就没跑完,待改进
  • 通过特征向量方法,将其进行KNN或者SVM分类之后得到结果

题外话:用face_recognition包和KNN分类实现

faces94,faces95,faces96,grimace四个数据集上了跑了跑。这个包能够直接通过face_recognition.face_encodings(image,known_face_locations=face_bounding_boxes[0])得到图像编码,将这个编码进行KNN分类即可。

结果

难点与改进

难点

  1. 光照问题
  2. 表情姿态问题
  3. 遮挡问题
  4. 年龄变化

改进与尝试

  1. 尝试MBLP、SURF, HOG和FHOG 特征提取算法
  2. 尝试深度学习等卷积神经网络特征提取
  3. 尝试SVM等其他分类算法
  4. 探究图像进行预处理(旋正,调节曝光)对结果的影响