模式识别实验:基于主成分分析(PCA)的人脸识别

这篇具有很好参考价值的文章主要介绍了模式识别实验:基于主成分分析(PCA)的人脸识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本文使用Python实现了PCA算法,并使用ORL人脸数据集进行了测试并输出特征脸,简单实现了人脸识别的功能。

1. 准备

ORL人脸数据集共包含40个不同人的400张图像,是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。此数据集包含40个类,每个类含10张图片。所有的图像是以PGM格式存储,灰度图,图像大小为 92 x 112像素。

对于每个类,我们选择前7张图片用于训练,后3张图片用于测试。我们将图像缩放至原来的0.5倍,以加快训练速度。最后选择100个特征向量进行降维。

import os
import cv2
import numpy as np
from typing import Union, LiteralString
import matplotlib.pyplot as plt
%matplotlib inline

scaled = 0.5 # 图像缩放至原来的scaled倍
train_num = 7   # 7张用于训练
img_num = 10    # 总共10张图片
num_k = 100 # 选择100个特征
save_path = './ORL_eigenfaces'
dataset_path = '../dataset/ORL/att_faces/'
cov_matrix_path = './PCA_ORL.npy'

2. 数据集处理

将每个类的前7张图片使用img2np转为一维向量,作为训练集。并计算每个类前7张图片的平均特征向量,用于后面的对比。

# 图像转为一维向量
def img2np(img_path: Union[str, LiteralString], scaled: float = 1.) -> np.ndarray:
    img = cv2.imread(img_path)
    h, w = img.shape[0], img.shape[1]
    img = cv2.resize(img, (int(h * scaled), int(w * scaled)))
    if img.shape[-1] > 1:
        img = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
    return np.array(img).flatten()
class_names = os.listdir(dataset_path)
print(f'数据集总共有 {len(class_names)} 个类')

# 列表示特征值,行表示图像
samples_data = []
avg_feature = [] # 每个类的平均特征

for class_name in class_names:
    class_path = os.path.join(dataset_path, class_name)
    img_names = os.listdir(class_path)
    class_feature = [] # 计算每个类前train_num的平均特征
    for img_name in img_names[:train_num]:  # 取前七张参与训练
        img_data = img2np(os.path.join(class_path,img_name), scaled=scaled)  
        
        samples_data.append(img_data)
        class_feature.append(img_data)
        
    avg_feature.append(np.array(class_feature).mean(axis=0))
samples_data = np.array(samples_data)
avg_feature = np.array(avg_feature)

print(f'数据集特征矩阵形状: {samples_data.shape},平均特征矩阵形状:{avg_feature.shape}')
数据集总共有 40 个类
数据集特征矩阵形状: (280, 2576),平均特征矩阵形状:(40, 2576)

3. PCA降维

PCA计算时间较长,因此建议先对图像进行缩放,并保存降维后的特征矩阵,方便后续调用。

# PCA算法保留前k个特征向量
def pca(X: np.ndarray, k: int) -> np.ndarray:  
    
    # 计算每个特征均值
    mean = np.mean(X, axis=0)
    # 数据标准化
    norm_X = X - mean
    # 计算协方差矩阵
    cov_matrix = np.cov(norm_X, rowvar=False)
    # 计算特征值与特征向量
    eig_val, eig_vec = np.linalg.eig(cov_matrix)
    abs_eig_vec = np.abs(eig_val)
    # 按照特征值的绝对值大小增序排序
    sorted_Index = np.argsort(abs_eig_vec)

    # 选择前k个特征值对应的特征向量
    selected_vectors = eig_vec[:, sorted_Index[-k :]]
    # 低维投影
    return selected_vectors
if os.path.exists(cov_matrix_path):
    pca_vectors = np.load(cov_matrix_path)
else:    
    pca_vectors = pca(samples_data, num_k) # 选择100个特征向量
    np.save(cov_matrix_path, pca_vectors) # 训练时间较长,可以保存方便调用
print(f'PCA降维后的特征矩阵形状: {pca_vectors.shape}')
PCA降维后的特征矩阵形状: (2576, 100)

4. 测试

假设有C个类,每个图像的特征值数为N,降维后选取的特征向量数为K。

首先对类的平均特征矩阵进行降维,降维后的矩阵形状为(C x K)。

测试时:

  1. 对每张测试图片进行降维:图像特征(1 x N)与PCA降维特征向量(N x K)相乘;
  2. 对第一步得到的结果与平均特征矩阵的每一行(每一行大小为1 x K)进行余弦相似度比较得到C个数;
  3. 选择C个数中最大的下标,就是预测的类别。
pca_avg_feature = np.dot(avg_feature, pca_vectors) # 进行降维
print(f'PCA降维后的平均特征矩阵形状: {pca_avg_feature.shape}')
PCA降维后的平均特征矩阵形状: (40, 100)
# 计算余弦相似度
def cosine_similarity(vec1: np.ndarray, vec2: np.ndarray):
    # 向量点乘
    dot_product = np.dot(vec1, vec2)

    # 计算L2范数
    magnitude1 = np.linalg.norm(vec1)
    magnitude2 = np.linalg.norm(vec2)

    # 计算余弦相似度
    return dot_product / (magnitude1 * magnitude2)

test_res = []
correct = 0
wrong = 0
for i, class_name in enumerate(class_names):
    class_path = os.path.join(dataset_path, class_name)
    img_names = os.listdir(class_path)
    true_label = i
    for img_name in img_names[train_num: img_num]:
        img_data = img2np(os.path.join(class_path, img_name), scaled=scaled)
        predict_img = np.dot(img_data, pca_vectors)
        similarity = []
        for j in pca_avg_feature:
            similarity.append(cosine_similarity(j, predict_img))
        predict_label = np.argmax(similarity)
        if true_label == predict_label:
            correct += 1
        else:
            wrong += 1
        test_res.append((true_label, predict_label))
accuracy = correct / (correct + wrong)
print(f'Total samples: {correct + wrong}, correct: {correct}, wrong: {wrong}, accuracy: {accuracy:.4f}')
Total samples: 120, correct: 111, wrong: 9, accuracy: 0.9250

5. 结果展示

将特征向量保存为特征脸并输出。此处注意下,缩放后的图像大小为56 x 46,但保存的特征脸大小为 46 x 56。

# 保存前k个特征向量的特征脸
def save_eigenfaces(eigenvectors: np.ndarray,
                    k: int,
                    img_size: tuple[int, int],  # (h, w)
                    path: Union[str, LiteralString]) -> bool:
    if os.path.exists(path) is False:
        os.mkdir(path)  # 创建保存路径文件夹
    for i in range(k):
        eigenfaces = np.real(eigenvectors[:, i])
        
        # 对特征向量进行归一化,投影到0-255的灰度空间
        norm_eigenfaces = ((eigenfaces - np.min(eigenfaces)) /
                                 (np.max(eigenfaces) - np.min(eigenfaces)) * 255)
        norm_eigenface_uint8 = norm_eigenfaces.astype(np.uint8)
        shaped_eigenface = norm_eigenface_uint8.reshape(img_size)
        cv2.imwrite(os.path.join(path, f'eigenfaces{i}.png'), shaped_eigenface)
    return True

save_eigenfaces(pca_vectors, 100, (46, 56), save_path)  # 原大小为112 x 92,缩放后为56 x 46

plt.figure(figsize=(8, 8))
for i in range(16):
    plt.subplot(4,4,i+1)
    plt.imshow(cv2.imread(os.path.join(save_path, f'eigenfaces{i}.png')))
    plt.title(f'eigenfaces{i}')
    plt.xticks([])
    plt.yticks([])
plt.show()

模式识别实验:基于主成分分析(PCA)的人脸识别

6. 总结

PCA可以实现简单的人脸识别。

环境配置:文章来源地址https://www.toymoban.com/news/detail-747838.html

matplotlib==3.7.2
numpy==1.25.2
opencv_python==4.8.1.78

到了这里,关于模式识别实验:基于主成分分析(PCA)的人脸识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据分析案例-基于PCA主成分分析法对葡萄酒数据进行分析

    🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 1.项目背景 2.项目简介 2.1分析目标 2.2数据集介绍 2.3技术工具 3.算法理论 4.实验过程

    2024年02月03日
    浏览(44)
  • R语言——采用主成分分析PCA方法下的“S 模式 “矩阵从同步分类中提取度量指标

    本教程将向您展示如何根据我们的综合分类计算一些指标。 PCA(Principal Component Analysis,主成分分析)是一种常用的数据降维技术,用于从高维数据中提取最重要的特征。它通过将原始数据转换为一组新的正交变量,称为主成分,以捕捉数据中最大的方差。 1. 数据标准化:如

    2024年03月15日
    浏览(53)
  • 机器学习:基于PCA对人脸识别数据降维并建立KNN模型检验

    作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍 📜📜📜如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!💪 大家好,我

    2024年02月01日
    浏览(40)
  • PCA分析(主成分分析)--结果解读

    主成分分析( PCA )是一个很好的工具,可以用来降低特征空间的维数。 PCA 的显著优点是它能产生不相关的特征,并能提高模型的性能。 PCA 用于减少用于训练模型的特征维度数量,它通过从多个特征构造所谓的主成分( PC )来实现这一点。 PC 的构造方式使得 PC1 方向在最大

    2024年02月03日
    浏览(37)
  • PCA主成分分析

    目前图像特征的提取主要有两种方法:传统图像特征提取方法 和 深度学习方法。 传统的特征提取方法:基于图像本身的特征进行提取(PCA); 深度学习方法:基于样本自动训练出区分图像的特征分类器; 特征选择(feature selection)和特征提取(Feature extraction)都属于 降维

    2024年02月08日
    浏览(53)
  • 主成分分析(PCA)详解

    主成分分析(PCA)是一种比较基础的数据降维方法,也是多元统计中的重要部分,在数据分析、机器学习等方面具有广泛应用。主成分分析目的是用较少的变量来代替原来较多的变量,并可以反映原来多个变量的大部分信息。 对于一个含有n个数据,变量的个数为p的一个样本,

    2024年01月17日
    浏览(44)
  • 主成分分析(PCA)原理详解

    在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律。多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的工作量。更重要的是在很多情形下,许多变量之间可能存在相关性,从而

    2024年02月07日
    浏览(46)
  • 主成分分析(PCA)实例讲解

        主成分分析(PCA)是一种降维算法,PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分(特征之间互相独立),是在原有n维特征的基础上重新构造出来的k维特征(k=n),会带来部分信息损失。     一般来说,当研究的问题涉及到多

    2024年02月09日
    浏览(45)
  • PCA主成成分分析例题详解

    主成分分析是一种降维算法,它能将多个指标转换为少数几个主成分,这些主成分是原始变量的线性组合,且彼此之间互不相关,其能反映出原始数据的大部分信息 需要了解具体细节可看此视频👉:什么是主成成分分析PCA 计算步骤 假设有 n n n 个样本, p p p 个特征,则可构

    2024年02月03日
    浏览(47)
  • 主成分分析(PCA)——矩阵角度推导

    最近机器学习课上正式讲了主成分分析,只是老师说的很快,我并没有完全理解。随后我搜了很多关于这方面的讲解来进行理解,仅CSDN上就有很多讲的很好的文章,从协方差矩阵角度进行说明,基本上我也都理解了。但另一方面我发现可以结合我最近学的矩阵分析,从纯矩阵

    2024年03月15日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包