基于PCA方法的ORL人脸识别及Python代码实现

您所在的位置:网站首页 pca实现人脸识别 基于PCA方法的ORL人脸识别及Python代码实现

基于PCA方法的ORL人脸识别及Python代码实现

2023-10-01 18:40| 来源: 网络整理| 查看: 265

基于PCA方法的ORL人脸识别及Python代码实现 PCA算法方案设计代码实现结果分析参考文献

PCA的理论知识已经有很多博客做了清晰的解释,主要概括为找到投影的面使得类间误差最大,转化为找到构建的协方差的特征值与特征向量,在新的投影方向(特征向量)上投影,构建数据库和待检索的人脸进行比对,得到相似度最高的人脸作为查询结果,本文使用ORL人脸数据库基于PCA方法实现人脸识别。

机器学习理论《统计学习方法》学习笔记:主成分分析(PCA)

本文所用的是ORL人脸库,由英国剑桥实验室拍摄,共有40人,每人不同角度不同表情拍摄了10张,所以共有400个样本数据,图片尺寸为112*92,格式为pgm。本文将每人的前5张作为训练集,后5张作为测试集。ORL人脸库可在该网址下载。

https://download.csdn.net/download/qq_40507857/13714311

PCA算法

设有m条n维数据: (1)将原始数据按列组成n行m列矩阵X (2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值 (3)求出协方差矩阵 (4)求出协方差矩阵的特征值及对应的特征向量 (5)将特征向量按对应特征值大小从上到下按行进行排列成矩阵,取前k行组成矩阵P (6)Y=PX即为降维到K维后的数据

方案设计 将ORL人脸数据库的40位志愿者的10张图片,使用10折交叉验证。每个人依次取出一张作为验证数据,进行10轮验证,最后得到准确率的均值。对于每次运算,训练集大小为360张图片,验证集大小为40张图片。对于每张图片,将其展开为一维向量 X i X_i Xi​;即训练集 X = X 1 , X 2 , ⋯   , X 3 60 X=X_1,X_2,\cdots,X_360 X=X1​,X2​,⋯,X3​60,维度为(10304,400).求X每行的均值向量u,并将其与X相减,进行零均值化,得到 C = ( X 1 − u , X 2 − u , ⋯   , X 3 60 − u ) C=(X_1-u,X_2-u,\cdots,X_360-u) C=(X1​−u,X2​−u,⋯,X3​60−u);构建协方差矩阵 C C T CC^T CCT求解协方差矩阵的特征值,选取最大的K个,求出对应的K个特征向量,并将其按列排成变换矩阵P,其维度为(10304*K);计算训练集的图片在上述特征向量下的投影,即为 Y i = P T ( X i − u ) Y_i=P^T(X_i-u) Yi​=PT(Xi​−u),作为查找集;将待识别的图片做以上相同投影运算得到Z;遍历搜索查找集,满足 m i n ∣ ∣ Y i − Z ∣ ∣ min||Y_i-Z|| min∣∣Yi​−Z∣∣条件的,即待识别图片与 Y i Y_i Yi​对应图片属于一类,即找到待识别照片的主人。

其中,构建的协方差矩阵 C C T CC^T CCT进行特征值与特征向量求解时非常耗时,所以构造 C T C C^TC CTC进行特征值和特征向量的求取,最后通过将求得的特征向量左乘C,即可得到 C T C C^TC CTC的特征向量。

代码实现 import cv2 import numpy as np import glob # 预处理 构建数据矩阵 images = glob.glob(r'.\ORL\*.bmp') X = [] for img in images: img = cv2.imread(img, 0) temp = np.resize(img, (img.shape[0] * img.shape[1], 1)) X.append(temp.T) X = np.array(X).squeeze().T print(X.shape, X.shape[1]) # (10304, 400) 400 # 10轮 correct_sum = 0 for epoch in range(10): # 10折交叉验证 数据划分 train_data = X[:, [x for x in list(range(X.shape[1])) if x not in list(range(epoch, X.shape[1], 10))]] test_data = X[:, list(range(epoch, X.shape[1], 10))] # train u = np.sum(train_data, axis=1) / train_data.shape[1] # 求均值向量 # 平均脸 # u = np.array(u, dtype='uint8') # average_face = np.resize(u, (img.shape[0], img.shape[1])) # cv2.imwrite('Average_Face.png', average_face) u = u[:, np.newaxis] C = train_data - u # 中心化后数据矩阵 Covariance = np.dot(C.T, C) # 构建协方差矩阵,一般为C .* C.T,但是构造这种类型可减少运算量 eigvalue, eigvector = np.linalg.eig(Covariance) # 由协方差矩阵求解特征值、特征向量 real_eigvector = np.dot(C, eigvector) # 通过之前的构造来恢复真正协方差矩阵对应的特征向量 sort = np.argsort(-eigvalue) # 将特征值从大到小怕排序,得到排序后对于原索引 P = real_eigvector.T[sort[0:100]] # 对于排序构造特征向量,取前面较大权重值 Y = [] for i in range(train_data.shape[1]): temp = train_data[:, i, np.newaxis] Y.append(np.dot(P, temp - u)) # 构建每幅图像投影后的值,构造查找表 # test correct = 0 for index in range(test_data.shape[1]): img_test = test_data[:, index, np.newaxis] # 从测试集提取单张人脸 Result = np.dot(P, img_test - u) # 计算待识别的人脸的投影 a = np.sum(abs(Y - Result), axis=1).argmin() # 遍历搜索匹配 if index * 9


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3