基于PCA的图像压缩及人脸识别算法

一、PCA基础知识

博文最后会附上例程代码~

PCA(Principal Component Analysis) 是一种常见的数据分析方式,常用于高维数据的降维,可用于提取数据的主要特征分量。
在统计学中,主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成分)上,第二大方差在第二个坐标(第二主成分)上,依次类推。主成分分析经常用于减少数据集的维数,同时保持数据集的对方差贡献最大的特征。这是通过保留低阶主成分,忽略高阶主成分做到的。这样低阶成分往往能够保留住数据的最重要方面。
在这里插入图片描述
如图所示,为数据在原始空间和PCA空间的表示,在原始空间,数据近似于随机分布,如果是随机数据则在每个坐标轴上都近似满足正太分布。经过PCA降维处理,将原始数据投影到新的正交子空间中,并且数据的主成分按照从大到小的顺序投影在各个正交基上,前k个大特征值对应的特征向量组成的基构成的子空间可以包含数据的绝大部分成分。仅对前k个维度数据进行处理即可近似地得到与原始数据相一致的结果,并且PCA降维后的数据因为其正交性,特征更加明显,可以应用于人脸识别中来。

近似地,有熟悉导航信号的同学可以发现,在导航信号中,对接收数据进行下变频并进行IQ分解也是一种投影技术。在这里,我们将导航信号投影到由sin和cos组成的正交基上,将接收数据的绝大部分分量投影到同相路中,而正交之路只包含有原始信号的一些相位特性。

二、 算法分析与MATLAB仿真

原始图像数据的处理

我们从数据集中获取的图像往往都是二维的,而在PCA分析中,我们需要将二维图像转换为一维列向量。
如下代码是将一个文件夹中的40个子文件夹中存放的400张人脸读取到数据矩阵A中,并将R×C大小的图片按列存储为RC×1,因为这里是400张112×92大小的图片,所以A矩阵大小为10304×400。

A = zeros(112*92,400);
for file_cnt = 1:400
    str = num2str(file_cnt);
    file_path1 = strcat('s',str);
    SamplePath1 = strcat('.\faces_dataset\att_faces\',file_path1,'\');  %存储图像的路径
    fileExt = '*.pgm';  %待读取图像的后缀名
    %获取所有路径
    files = dir(fullfile(SamplePath1,fileExt)); 
    len1 = size(files,1);
    %遍历路径下每一幅图像
    for file_cnt2=1:len1
        fileName = strcat(SamplePath1,files(file_cnt2).name); 
        image = imread(fileName); 
        A(:,((file_cnt-1)*10)+file_cnt2) = reshape(image,10304,1);
    end
end

对原始数据进行特征值分解

对数据矩阵A得到特征值的方法有两种,特征值分解法和SVD分解法,二者最后的结果都是得到原始数据的特征值和特征向量。特征值分解原理方法步骤这里不再赘述,直接上算法步骤:
这里用的是SVD分解法:

%PCA
[V, L, mu] = cw_pca(A);
% Subtract the mean from data
A_ZeroMean = bsxfun(@minus, A, mu);%所有样本去掉均值脸

其中V和L是经过降序排列的特征向量和特征值,mu是均值脸,在进行投影变换前要对样本去掉均值脸。
如下图可以看到这组数据的均值脸:
在这里插入图片描述

对图像数据降维后的各维度所占能量进行分析

前K维的特征值及前K维空间中图像数据投影后所占能量。

eigenenergy = zeros(1,400);
for cnt = 1:400
    if cnt == 1
        eigenenergy(cnt) = L(cnt);
    else
        eigenenergy(cnt) =  eigenenergy(cnt-1) + L(cnt);
    end
end
%归一化
eigenenergy = eigenenergy./eigenenergy(400);
figure(3)
plot(1:400,eigenenergy);

结果如图所示;
在这里插入图片描述
共400个维度,前若干个特征值即占有了绝大部分能量。

图像质量随维度数的变化

将图像投影到全维特征子空间中为下图中最后一幅图像所示,将子空间维度10等分,依次选取前若干份维度的信息进行投影变换,得到的图像重建质量如下图所示:
在这里插入图片描述
图像的投影与反投影函数:

A_14_z = A_ZeroMean;
% P = A'*V;%投影,两种投影均可
% A_unprj = V * P'; %反投影
P = V'* A_14_z;%投影
A_unprj = V * P; %反投影
A_unprj = A_unprj + repmat(mu,1,size(A_unprj,2)); %加上均值;

降维后截取前K个特征值的方法是:

A_14_z = A_ZeroMean;
V_i = V(:,1:K);%取其前K个特征向量
P = V_i'* A_14_z;%投影
A_unprj = V_i * P; %反投影
A_unprj = A_unprj + repmat(mu,1,size(A_unprj,2)); %加上均值;

我们还可以用RMSE(均方根误差)来作为图像重建质量的评价标准,通过将截断值K从1选到400,查看其RMSE误差:
在这里插入图片描述

不同人脸的特征投影

取其第1和第2个特征向量作为2维坐标系的横轴和纵轴,画出6个不同人脸在这2个维度上的坐标。每张人脸10副图像,即10个点:
在这里插入图片描述
随后在其前3个大特征值对应的特征向量组成的三维坐标系中观察这种分类现象:
在这里插入图片描述

投影分析与量化

实际应用中为了控制压缩比,经常需要对数据进行量化,我们这里对投影后的结果矩阵进行量化,首先对其进行分析。结果矩阵如下图所示,值随着维度的增大而减小。
在这里插入图片描述
这里比较了两种量化方法 ,一种是整体进行8bit量化,另一种是前50个点进行8bit量化,后250个点进行4bit量化,下方贴出了两种量化方法RMSE误差随压缩比(这里固定量化方式,改变维度截断系数K来改变压缩比)改变而改变的情况。
在这里插入图片描述

人脸识别

下边分析基于前述讨论的人脸识别方法

单张人脸图片的测试

首先进行但张人脸的识别分析,从40个人的400张图片中取出一个人的某张图片作为测试图片,将其余399张图片作为训练集进行PCA投影,这一步即训练部分,将训练集的部分特征分解投影变换到一组正交基张成的低维子空间,从而将其特征保留下来。
分别将训练集和测试图片在PCA后的基上进行投影,下图画出了5个人在基上前3个维度的坐标,红色是被测试者,红色星状点是被测试者未被训练的人脸图片。通过子空间分析可以发现,除了各个人的人脸特征进行了聚类外,与被测人脸有同样特征的未训练数据也被投影到了相近的位置。
由此进行分析,将每个人的10组投影值进行求平均,得到这个人在这个训练集下PCA投影点的质心保存下来,然后判断未被训练的新图片距离质心的距离即可判断是否是这个人的人脸,机器也就能学习到这个人脸的特征,并进行识别。
在这里插入图片描述

人脸识别概率测试

首先计算40个人脸投影值的质心,下方左侧图片是400张图片各自的投影值,右侧是求质心后的40个投影值。
在这里插入图片描述
对400张图片每个都进行人脸识别测试,统计其正确概率即可得到人脸识别正确率,检测结果成功率为87%。
通过对被测图像进行预处理,可以提高检测概率。

后边写的人脸识别的代码有点随意,所以只贴了前半部分PCA压缩和特征分析的代码,全部代码在网盘中。
网盘链接
提取码:yyy4

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值