基于SVD奇异值分解算法的人脸身份识别matlab仿真

发布时间 2023-07-25 15:28:31作者: 简简单单做算法

1.算法理论概述

       人脸身份识别是计算机视觉领域中的一个重要研究方向,它可以对人脸图像进行识别和验证。人脸身份识别在人脸识别门禁系统、安全监控等领域有着广泛的应用。将介绍一种基于SVD奇异值分解算法的人脸身份识别方法,该方法使用SVD分解将人脸图像表示为低维特征向量,然后使用最近邻分类器将待分类的人脸图像与已知的人脸图像进行比较。

 

特征提取

        人脸身份识别算法的第一步是对人脸图像进行特征提取,将人脸图像转化为特征向量。常用的特征提取方法包括主成分分析(PCA)和线性判别分析(LDA)。在本文中,我们将使用SVD奇异值分解来提取人脸图像的特征向量。具体地,我们将人脸图像表示为一个矩阵X,其中每一列代表一张人脸图像,然后对X进行SVD分解,即

 

 

其中,$\delta(c_i,c_j)$是一个指示函数,当$c_i=c_j$时取值为1,否则取值为0。

 

实现步骤

 

数据预处理

        在实现算法之前,我们需要进行数据预处理,将人脸图像转化为矩阵形式。具体地,我们可以将每张人脸图像转化为一个向量,然后将这些向量按列排列成一个矩阵$X$。在这个矩阵中,每一列代表一张人脸图像,每一行代表一维特征。我们可以使用标准的图像处理库,如OpenCV和PIL来实现这个步骤。

 

SVD分解

        在进行SVD分解之前,我们需要对数据进行归一化处理,将每一维特征都缩放到相同的范围内。常用的归一化方法包括将每一维特征都减去均值,然后除以标准差。然后,我们对归一化后的矩阵$X$进行SVD分解,得到三个矩阵$U$,$\Sigma$和$V^T$。我们可以根据需要保留前$k$个奇异值,然后将$U_k$作为特征向量,即

 

 

 

最近邻分类器

       在进行最近邻分类器之前,我们需要将已知的人脸图像集合$D$划分为训练集和测试集。通常情况下,我们将80%的图像作为训练集,剩下的20%的图像作为测试集。对于每个测试样本,我们将它的特征向量$f(x)$与训练集中的所有样本进行比较,选取距离最近的$n$个样本,并将它们所属的身份类别作为预测类别。在实现最近邻分类器时,我们可以使用Python中的scikit-learn库来实现。

 

2.算法运行软件版本

MATLAB2022a

 

3.算法运行效果图预览

 

 

 

4.部分核心程序

% 计算每个已知个体的坐标向量xi
rank = size(A, 2); 
xi = u(:, 1:rank)' * A;
% 定义阈值,这些值是通过反复试验来定义的
epsilon_0 = 50; % 与训练集中任何已知人脸的最大允许距离S
epsilon_1 = 15; % 与面空间的最大允许距离
% 分类
images{1}     = ['test/1.jpg']; 
images{2}     = ['test/3.jpg']; 
images{3}     = ['test/5.jpg']; 
images{4}     = ['test/11.jpg']; 
images{5}     = ['test/25.jpg']; 
images{6}     = ['test/nothing.jpg']; 
images{7}     = ['test/X.jpg']; 
figure;% 创建一个新的图形窗口
for jj = 1:length(images)
images{jj}
epsilons   = zeros(N, 1); % 初始化距离向量
test_image = readImage(images{jj});% 读取待识别图像
test_image = test_image(:) - train_mean; % 标准化测试图像
x = u(:, 1:rank)' * test_image; % 计算测试图像的坐标向量x
epsilon_f = ((test_image - u(:, 1:rank) * x)' * (test_image - u(:, 1:rank) * x)) ^ 0.5;
subplot(3,3,jj); % 在图形窗口中创建一个子图
imshow(readImage(images{jj}),[]);% 显示待识别图像
% 检查它是否在面空间中
if epsilon_f < epsilon_1
   % 计算待识别图像到人脸空间的距离ε
    for i = 1:N
        epsilons(i, 1) = (xi(:, i) - x)' * (xi(:, i) - x);
    end
    [val idx] = min(epsilons(:, 1)); % 找到到人脸空间距离最近的已知个体
    if val < epsilon_0% 如果到已知个体的最大允许距离内
        disp(sprintf('当前测试图片属于图片序号 %d', idx));% 输出识别结果所属的个体编号
        title(['当前测试图片属于图片序号:', num2str(idx)]); % 在子图中添加标题显示识别结果
    else
        disp('未知人脸');% 输出无法识别的结果
        title(['未知人脸']);% 在子图中添加标题显示无法识别的结果
    end
else
    disp('当前输入图片不存在人脸图片'); % 输出输入图像中不存在人脸的结果
    title(['不存在人脸']);% 在子图中添加标题显示输入图像中不存在人脸的结果
end
 
checks(jj)=val;% 将到人脸空间距离最近的已知个体与待识别图像的距离保存到checks向量中
 
end