OpenCV使用Fisherfaces算法,实现人脸识别对比

Fisherfaces使用LDA(Linear Discriminant Analysis,线性判别分析)实现人脸识别。线性判别识别最早由Fisher在1936年提出,是一种经典的线性学习方法,也称为“Fisher判别方法”。

一、基本原理
线性判别分析在对特征值降维的同时考虑类别信息。其主要思路为:在低维表示下,相同的类应该紧密聚集在一起;不同的类应该尽可能的分开且距离应尽可能远。即线性判别分析要尽力满足一下两个要求:
·类别之间的差别尽可能地大
·类别之间的差别尽可能地小

做线性判别分析时,首先将训练样本投影到一条直线A上,让投影后的点满足:
·异类之间的点尽可能地远离
·同类之间的点尽可能地靠近

做完投影后,将待测样本投影到直线A上,根据投影点的位置判断样本的类别,就完成了识别。

例如:下图为一组训练样本集,现在需要找到一条直线,让所有样本满足:
异类之间的点尽可能地远离,同类之间的点尽可能地靠近
在这里插入图片描述
下图左右两图分别有两条不同投影线L1和L2,将上图中的样本投影到这两条线上,可以看到下图中L2的投影效果要好于在L1上的投影结果。
在这里插入图片描述
如上图所示线性判别分析找到的最优的投影线,A B样本组内样本之间的距离要尽可能的近,C的组间的距离要尽可能的远。找到这样一条直线后,如果要判断某个待测样本的分组,可以将该样本点向投影线投影,然后根据投影点的位置来判断其所属类别。
例如下图中,三角形样本U向投影线投影后,其投影点在原点的投影范围内,则认为该样本点U属于圆点所在分类。
在这里插入图片描述
二、函数介绍
Opencv提供函数:cv2.face.FisherFaceRecognizer_create()生成Fisherfaces识别实例模型,然后应用cv2.face_FaceRecognizer.train()函数完成训练,用cv2.face_FaceRecognizer.predict()函数完成人脸识别。

1.cv2.face.FisherFaceRecognizer_create()
该函数语法格式:r1 = cv2.face.FisherFaceRecognizer_create(num_components,threshold)
两个参数都为可选参数,他们的定义为:
num_components:使用Fisherfaces准则进行线性判别分析时保留的成分数量。可以采用默认值“0”
threshold:进行识别时所用的阈值。如果最近的距离比设定的阈值threshold还要大,函数返回1

2.cv2.face.FisherFaceRecognizer.train()
该函数对每个参考图像进行Fisherfaces计算,得到一个向量。每个人脸都是整个向量集中的一个点。该函数的语法格式为:
no = cv2.face.FisherFaceRecognizer.train(src,labels)
src:训练图像,用来学习的图像。
labels:人脸图像所对应的标签。
该函数没有返回值。

3.cv2.face_FaceRecognizer.predict()
该函数在对一个待测人脸图像进行判别时,寻找与其距离最近的人脸图像,将其识别为对应的标签。语法格式:
label,confidence=cv2.face_FaceRecognizer.predict(src)
src:需要识别的人脸图像。
label:返回识别结果的标签。
confidence:置信度评分,用来衡量识别结果与原有模型之间的距离。0表示完全匹配。该值通常在0到20000之间,若低于5000则认为是相当可靠的识别结果。

下面介绍简单的人脸识别示例:
(运行环境:PyCharm+python3.7+opencv4.5.1.48)
先有五张图,其中前四张作为训练集(图1、4为一组标签为0,图2、3为一组标签为1),另外一张为测试:
1.                   2.                     3.                     4.                     5.
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
代码:

import cv2
import numpy as np
images = []
# 这里因为需要我将照片导入前已经调整为一样大小,如果嫌麻烦可以在代码中将图像resize成一样大的,这里在给出
ima = cv2.imread("img/1.png", cv2.IMREAD_GRAYSCALE)
imb = cv2.imread("img/4.png", cv2.IMREAD_GRAYSCALE)
imc = cv2.imread("img/2.png", cv2.IMREAD_GRAYSCALE)
imd = cv2.imread("img/3.png", cv2.IMREAD_GRAYSCALE)
images.append(ima)
images.append(imb)
images.append(imc)
images.append(imd)
# 前两张标签为0,后两张标签为1
labels = [0, 0, 1, 1]
# print(labels)
recognizer = cv2.face.FisherFaceRecognizer_create()
recognizer.train(images, np.array(labels))
predict_image = cv2.imread("img/5.png", cv2.IMREAD_GRAYSCALE)
label, confidence = recognizer.predict(predict_image)
# 输出匹配的人脸图像标签,0或1
print("label=", label)
# 输出置信读
print("confidence=", confidence)
# 显示训练集中最为匹配的图像
 

运行结果:
在这里插入图片描述
可以看到匹配的标签为1,置信读为1687多
假设如果将图1、4,2、3标签互换输出结果应该是标签0,结果如下:
在这里插入图片描述
正确🙊👏🏻👏🏻
参考书籍:《OpenCV轻松入门:面向Python》李宗立.电子工业出版社.

 
posted @ 2021-05-20 12:57  好的!文西  阅读(1951)  评论(1编辑  收藏  举报