机器学习之基于PCA的人脸识别

news2024/11/23 9:12:07

目录

PCA人脸数据降维

matlab代码实现 

思路分析 

PCA人脸重构

matlab代码实现 

思路分析 

PCA人脸可视化

matlab代码实现 

思路分析: 

PCA人脸识别

matlab代码实现 

思路分析 


PCA人脸数据降维

matlab代码实现 

pictures=dir('C:\Users\Yezi\Desktop\机器学习\实验1:PCA算法\face10080\*.bmp');
sample=[];% 样本矩阵
for i=1:length(pictures)
    picture=imread("C:\Users\Yezi\Desktop\机器学习\实验1:PCA算法\face10080\"+pictures(i).name);
    picture=double(picture);
    picture=picture(:);% 单张图片拉成列向量
    sample=[sample,picture];
end
% PCA 主流程
meanFace=mean(sample); % 求样本均值
meanFace=ones(size(sample,1),1)*meanFace;% 矩阵化样本均值
sample=sample-meanFace; % 样本中心化:减去样本均值
covMatrix=sample*sample';% 求样本的协方差矩阵
[egienvectors,diagonalMatrix]=eig(covMatrix);% 协方差矩阵的特征值分解
egienvalues=diag(diagonalMatrix);% 取特征值
[egienvalues,order]=sort(egienvalues,'descend');% 特征值降序排序
egienvectors=egienvectors(:,order);% 将特征向量按特征值降序排序

思路分析 

这段代码是一个简单的PCA(主成分分析)算法实现,用于对图像数据进行降维处理。下面是对代码进行逐行分析:

  1. pictures=dir('C:\Users\Yezi\Desktop\机器学习\实验1:PCA算法\face10080\*.bmp'); 这行代码使用dir函数获取指定文件夹中的所有.bmp格式的文件名,并将结果存储在pictures变量中。

  2. sample=[];% 样本矩阵 sample变量用于存储图像样本数据,初始化为空矩阵。

  3. for i=1:length(pictures) for循环遍历pictures中的每个文件名。

  4. picture=imread("C:\Users\Yezi\Desktop\机器学习\实验1:PCA算法\face10080\"+pictures(i).name); 该行代码使用imread函数读取指定路径下的图像文件,并将图像数据存储在picture变量中。

  5. picture=double(picture);picture转换为double类型,以便后续计算。

  6. picture=picture(:);% 单张图片拉成列向量picture变量转换为列向量的形式。

  7. sample=[sample,picture]; 将当前处理的图像样本添加到sample矩阵中。

  8. end for循环结束。

  9. meanFace=mean(sample); % 求样本均值 计算sample矩阵中每个特征的均值,结果存储在meanFace变量中。

  10. meanFace=ones(size(sample,1),1)*meanFace;% 矩阵化样本均值 将样本均值重复扩展为与sample矩阵相同大小的矩阵。

  11. sample=sample-meanFace; % 样本中心化:减去样本均值sample矩阵进行样本中心化处理,即将每个样本减去对应特征的均值。

  12. covMatrix=sample*sample';% 求样本的协方差矩阵 计算样本的协方差矩阵,即将样本矩阵乘以其转置。

  13. [egienvectors,diagonalMatrix]=eig(covMatrix);% 协方差矩阵的特征值分解 对协方差矩阵进行特征值分解,将特征向量存储在egienvectors中,特征值存储在diagonalMatrix的对角线上。

  14. egienvalues=diag(diagonalMatrix);% 取特征值 将特征值从diagonalMatrix的对角线提取出来,并存储在egienvalues中。

  15. [egienvalues,order]=sort(egienvalues,'descend');% 特征值降序排序 将特征值按降序进行排序,并同时记录排序后的索引,排序结果存储在egienvalues中。

  16. egienvectors=egienvectors(:,order);% 将特征向量按特征值降序排序 将特征向量按照特征值的降序排序,排序结果存储在egienvectors中。

以上就是给出的代码的分析,该代码主要实现了对图像数据进行PCA算法处理,得到图像数据的主成分特征向量。

PCA人脸重构

 

matlab代码实现 

oneFace=sample(:,1);
for dimension=20:20:160
    egienvector=egienvectors(:,1:dimension);
    rebuildFace=egienvector*(egienvector'*oneFace);
    rebuildFace=reshape(rebuildFace,100,80);
    index=dimension/20;
    subplot(2,4,index);
    imshow(mat2gray(rebuildFace));
    xlabel(sprintf("dimension=%d",dimension));
end

思路分析 

这段代码是用于对人脸进行重构并显示的部分,下面是对代码进行逐行分析:

  1. oneFace=sample(:,1); 从样本中选取第一张人脸作为重构对象,将其存储在oneFace变量中。

  2. for dimension=20:20:160 for循环迭代每个不同的维度值,从20开始,每次增加20,直到达到160。

  3. egienvector=egienvectors(:,1:dimension); 根据给定的维度值,选择相应数量的特征向量,将它们存储在egienvector变量中。

  4. rebuildFace=egienvector*(egienvector'*oneFace); 利用选定的特征向量重构人脸,将结果存储在rebuildFace变量中。这里的计算过程是通过将特征向量与其转置相乘来实现。

  5. rebuildFace=reshape(rebuildFace,100,80); 将重构后的人脸变形为原始图像的大小,即100x80像素。

  6. index=dimension/20; 计算当前维度值对应的索引,用于确定子图的位置。

  7. subplot(2,4,index); 创建一个2x4的子图网格,并选择第index个子图作为当前维度值的显示位置。

  8. imshow(mat2gray(rebuildFace)); 将重构的人脸图像显示在当前子图中。mat2gray函数用于将图像数据转换为灰度范围0-1之间的值,以便正确显示。

  9. xlabel(sprintf("dimension=%d",dimension)); 在当前子图的x轴标签位置显示当前维度值。

通过以上代码,可以实现基于不同维度的特征向量重构人脸,并将结果显示在一个子图网格中。每个子图对应一个特定的维度值,同时还在每个子图上方显示该维度的标签。这样可以观察不同维度下重构人脸的效果,并比较不同维度对重建结果的影响。

PCA人脸可视化

二维

 

三维

 

matlab代码实现 

visualizeDataTemp=[];
%5个人
for i=0:4
    visualizeDataTemp=[visualizeDataTemp,sample(:,i*10+1:i*10+10)];
end

for dimension=2:3
    egienvector=egienvectors(:,1:dimension);
    visualizeData=egienvector'*visualizeDataTemp;
    colors=[];
    for i=1:50
        color=floor((i-1)/10+1)*20;
        colors=[colors,color];
    end
    if dimension==2
        scatter(visualizeData(1,:),visualizeData(2,:),[],colors);
    else
        scatter3(visualizeData(1,:),visualizeData(2,:),visualizeData(3,:),[],colors);
    end
end

思路分析: 

这段代码是用于对经过PCA降维的人脸样本进行可视化的部分,下面是对代码进行逐行分析:

  1. visualizeDataTemp=[]; 创建一个空矩阵visualizeDataTemp,用于存储可视化数据。

  2. for i=0:4 for循环迭代5次,从0到4。

  3. visualizeDataTemp=[visualizeDataTemp,sample(:,i*10+1:i*10+10)]; 将每个人的10个人脸样本按列连接起来,并添加到visualizeDataTemp中。这样,visualizeDataTemp将包含50个人脸样本。

  4. for dimension=2:3 for循环遍历每个指定的维度值,从2到3。

  5. egienvector=egienvectors(:,1:dimension); 根据给定的维度值,选择相应数量的特征向量,将它们存储在egienvector变量中。

  6. visualizeData=egienvector'*visualizeDataTemp; 将选择的特征向量与样本数据进行相乘,得到降维后的可视化数据,存储在visualizeData变量中。

  7. colors=[]; 创建一个空矩阵colors,用于存储数据点的颜色信息。

  8. for i=1:50 for循环遍历50次,对于每个数据点。

  9. color=floor((i-1)/10+1)*20; 根据数据点的索引,计算对应的颜色值。这里使用(i-1)/10+1来确定颜色分组,然后乘以20得到颜色值。

  10. colors=[colors,color]; 将计算得到的颜色值添加到colors矩阵中。

  11. if dimension==2 判断当前维度是否为2。

  12. scatter(visualizeData(1,:),visualizeData(2,:),[],colors); 使用散点图将二维可视化数据绘制出来,各个数据点的坐标由visualizeData给出,颜色由colors指定。

  13. else 如果当前维度不是2。

  14. scatter3(visualizeData(1,:),visualizeData(2,:),visualizeData(3,:),[],colors); 使用3D散点图将三维可视化数据绘制出来,各个数据点的坐标由visualizeData给出,颜色由colors指定。

通过以上代码,可以将经过PCA降维处理的人脸样本进行可视化展示。具体而言,对于每个维度值,将选择相应数量的特征向量,并将样本数据投影到这些特征向量上,得到降维后的可视化数据。然后使用散点图或3D散点图将数据点绘制出来,并根据数据点的分组信息为其指定不同的颜色。这样可以观察不同维度下人脸样本在降维空间中的分布情况。

PCA人脸识别

不同维度的识别率

不同knnk值的识别率

matlab代码实现 

trainNumber=5;
testNumber=6;
trainData=[];
testData=[];
for i=0:14
    trainData=[trainData,sample(:,i*11+1:i*11+trainNumber)];
end
for i=0:14
    testData=[testData,sample(:,i*11+trainNumber+1:i*11+11)];
end
result=[];
for knnK=1:8
    for dimension=10:10:160
        egienvector=egienvectors(:,1:dimension);
        trainDataTemp=egienvector'*trainData;
        testDataTemp=egienvector'*testData;
        error=0;
        testDataNumber=size(testDataTemp,2);
        trainDataNumber=size(trainDataTemp,2);
        for i=1:testDataNumber
            distances=[];
            for j=1:trainDataNumber
               distance=0;
               for k=1:dimension
                  distance=distance+(testDataTemp(k,i)-trainDataTemp(k,j))^2; 
               end
               distances=[distances,distance];
            end
            [distances,index]=sort(distances);
            rightIndex=floor((i-1)/testNumber)+1;
            testIndex=0;
            knn=[];
            for k=1:knnK
               knn=[knn,floor((index(k)-1)/trainNumber)+1];
            end
            [modeIndex,times]=mode(knn);
            if times==1
                testIndex=knn(1);
            else
                testIndex=modeIndex;
            end
            if testIndex~=rightIndex
                error=error+1;
            end
        end
        rate=(testDataNumber-error)/testDataNumber;
        result=[result,rate];
    end
end
X=10:10:160;
Y=1:8;
result=reshape(result,16,8);
result=result';
waterfall(X,Y,result);%不同k值不同维度的识别率
%plot(X,mean(result));%不同维度的平均识别率

思路分析 

  1. 设置训练样本数trainNumber为5,测试样本数testNumber为6。

  2. 创建空矩阵trainDatatestData,用于存储训练数据和测试数据。

  3. 使用两个循环,将样本数据按列连接,并存储到trainDatatestData中。每个循环迭代15次,每次连接11个样本。

  4. 创建空矩阵result,用于存储不同k值和维度下的识别率。

  5. 使用两个嵌套循环,分别遍历k值和维度范围。在每次循环中,选择相应数量的特征向量,将训练数据和测试数据投影到这些特征向量上,得到降维后的数据。

  6. 初始化误差error为0,并计算训练数据和测试数据的数量。

  7. 使用两个嵌套循环,分别遍历测试数据和训练数据。在每次循环中,计算测试数据点与每个训练数据点之间的欧氏距离。

  8. 对距离进行排序,并记录距离最近的k个训练数据点的索引。

  9. 根据距离最近的k个训练数据点的类别,确定测试数据点的类别。如果存在多个最近邻居属于同一类别,则使用出现次数最多的类别作为测试数据点的类别。

  10. 如果测试数据点的类别与正确类别不一致,则增加误差计数。

  11. 计算识别率,并将结果存储到result中。

  12. 将一维结果矩阵result转换为二维矩阵,以便后续绘制图形。

  13. 使用waterfall函数绘制不同k值和维度下的识别率瀑布图,横轴为维度范围,纵轴为k值,瀑布图的高度表示识别率。

  14. 使用plot函数绘制不同维度下的平均识别率曲线。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/685667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字逻辑与模拟电子技术-部分知识点(2)——模电部分-半导体三极管、基本线性运放电路、正弦波振荡电路

目录 半导体三极管 三极管的放大的条件 基本放大电路计算 基本线性运放电路 同相放大电路 反相放大电路 加法器放大电路 正弦波振荡电路 正弦波振荡的条件 半导体三极管 三极管的放大的条件 主要是依靠它的发射极电流能够通过基区传输,然后到达集电极而实现…

【KMP算法】时间复杂度O(N)的字符串匹配算法

目录 案例:假定我们给出字符串 ”ababcabcdabcde”作为主串, 然后给出子串: ”abcd”,现在我们需要查找子串是否在主串中 出现,出现返回主串中的第一个匹配的下标,失败返回-1 ; 1.BF算法(暴力算法&#x…

java8新特性之--强大的Stream API详细讲解

强大的Stream API Stream API说明 Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则 是 Stream API。Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。 这是目前为止对Java类库最好的补充,因为Stream API可以极…

CVPR 23 | 高分辨率缺陷异常定位新范式:PyramidFlow

来源:投稿 作者:橡皮 编辑:学姐 论文链接:https://arxiv.org/abs/2303.02595 论文代码:暂未发布 0. 背景 由于复杂的工业制造过程中的不可控因素,不可避免地会给产品带来不可预见的缺陷。由于人类视觉系…

使用亮数据Bright Data解决出境电商问题

目录 一、出境电商的困境和问题1、困境一:获取准确的市场数据(1)数据的时效性和可靠性(2)数据的全面性和多样性(3)数据的实时更新和持续监测 2、困境二:克服地域限制和语言障碍&…

scratch数星星 2023年5月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析

目录 scratch数星星 一、题目要求 1、准备工作 2、功能实现 二、案例分析

基于Java学生信息管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

vue中js实现点击复制文本到剪贴板-三种方案

vue中js实现点击复制文本到剪贴板-三种方案 因为在网上找了一些很杂乱 不适用 所以自己写一篇记录分享一下 vue中js实现点击复制文本到剪贴板-三种方案 效果: 方案一:使用原生API(clipboard) 首先,我们需要安装clip…

【嵌入式5】电源相关芯片驱动

文章目录 1.读MPS5023芯片:0x03ff即将前6位屏蔽2.读PXE1410CDM电压和电流:一个数&0x7ff,将这个数前5位全变为0,其余位不变2.1 1ine11:先看第15和10位,e9b6是上面读出的值2.2 1ine16:PMBUS协…

产品的0到1概念篇

一、产品是什么? 产品是指被人们使用和消费,并能满足人们某种需求的任何东西,包括有形的物品、无形的服务、组织、观念或它们的组合。 产品本质是什么,产品的本质就是解决⽤户的痛点/满⾜⽤户的需求,这种满⾜的需求&…

KingbaseES的学习心得和知识总结(二)|Kingbase数据库闪回功能及插件kdb_flashback的使用

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、KingbaseES V8产品文档首页,点击前往 2、Kingbase 文档库,点击前往 3、北京人大金仓信息技术股份有限公司 官网首页,点击前往…

详解服务器端渲染 页面(SSR)

💌目录 🔥先了解服务器端渲染 (SSR)?🔥服务器端渲染的优点是什么呢?🔥有优点就有缺点?🔥根据Express来简单的建立一个服务端渲染 🔥先了解服务器端渲染 (SSR)&#xff1f…

Qt6.2教程——7.QT常用控件QTextEdit

一,QTextEdit简介 QTextEdit 是 Qt 的一个用于编辑和显示纯文本和富文本的控件。它是功能强大且高度灵活的,可以用于实现多种任务,如文本编辑,数据表示,以及HTML的显示和编辑等。QTextEdit 支持富文本功能&#xff0c…

Over 函数的使用

序言 其实也很少使用这个Over函数,毕竟mysql在5.7版本之前都是不支持的,但是over()的窗口概念被Flink中的窗口中借鉴了. 所以了解下,网上的Over()的使用有在Mysql中的例子,但是我的Mysql5.7 不支持,所以在Oracle中实验.但是语法都是一样的.cuiyaonan2000163.com 众所周知如果S…

转战VUE3学习

安装好vue3后,开始新的项目吧! npm init vuelatest1.组合式API 在以前vue2的项目里,使用的选项式API将各种不同逻辑的代码分散到像data、methods等不同的对象里。如果想看某一方面的逻辑,鼠标滚轮都要磨出火星了! 而…

LLM的工程实践思考

陆奇博士的主题演讲《新范式 新时代 新机会》非常震撼人心。我远程参加了深圳站和北京站两场演讲,深受感触。虽然了解大模型的机制和原理以了解新的范式非常重要,但是“行胜于言”,基于大模型的众多应用都需要工程技术才能落地。然而&#xf…

Ndk c++层 crash问题分析

首先你要从设备上拿到墓碑文件:tombstone,这里面会记录系统崩溃时的信息。位置在/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号&…

FlashAttention和PagedAttention

FlashAttention FlashAttention一般指的是FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness这篇,当然Transformer Quality in Linear Time这篇里非要说FLASH Fast Linear Attention with a Single Head,命名有点无语&…

JavaScript数据存储方式

内置对象 js内部提供的对象,包含各种属性和方法给开发者调用 document.write() console.log() Math Math对象是js提供的一个 “数学”对象,提供了一系列做数学运算的方法 max找最大值Math.max(3,8,5,4) 返回8min找最小值Math.min(3,8,5,4) 返回4ab…

printf不一样的玩法

Printf不一样的玩法 ❝ 在使用linux终端命令的时候,我们可以看到像more命令,它的显示方式与一般的字符串不同,是用了反显。同样,linux C下printf还有很多其他不常见的格式化输出形式。本文主要为你盘点这些形式。 ❞ 先看下效果&a…