PCA人脸识别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ermeiyao11/article/details/64605055

PCA人脸识别(带matlab程序)

前几天上数字图像处理的时候学习了PCA人脸识别,趁热打铁,做一些学习记录。PCA(Principal Component Analysis)是一种常用的数据分析方法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。在人脸识别上面,用PCA的主要目的就是把原来维度很高的图像,提取图像的主要成分(用于识别的特征),去掉不重要的成分,使得可以用比较少的维度来表示图像,以方便进行图形识别。

一个非常不错的学习PCA资料PCA数学原理

看完这个应该对PCA 的原理有了更深刻的认识。

下面是matlab代码


%
%测试数据:40人,每人10张照片。每人取前ph张照片作为训练集,后(10-ph)张照片作为测试集。
clear;
clc;
ph=6;
%%
%第一步:计算特征脸并创建特征空间

tic %计算运行时间
%申请录入数据矩阵内存
imdata=zeros(112*92,40*ph);
for i=1:40    
    for j=1:ph  
%         addr=strcat('G:/orl_face/s',num2str(i),'/',num2str(j),'.pgm');
         addr=strcat('G:/orl_face/s',num2str(i),'/',num2str(j),'.pgm');
        a=imread(addr);%从地址中读入图像
        b=a(1:112*92); %把图像a矩阵按列顺序转为行向量b
        imdata(:,ph*(i-1)+j)=b'; %把b的转置矩阵存放到imdata矩阵的第ph*(i-1)+j列
    end; 
end;

%计算平均脸
 imaverage=mean(imdata,2); %按行求平均mean(a,2)  按列mean(a)
 %显示平均脸
 %向量矩阵化

    out=reshape(imaverage,112,92);
    figure;
    subplot(1,1,1);
    imshow(out,[]);
    title(strcat('MeanFace'));

clear i j a b addr 

%图像预处理
immin=zeros(112*92,40*ph);
for i=1:40*ph  
    %归一化处理,提升矩阵计算速度,但小数精度不够,会影响匹配率
    %immin(:,i) = (imdata(:,i)-imaverage)/col2medivation(imdata(:,i)-imaverage,112*92);
    %仅减去平均脸,不做归一化处理
    immin(:,i) = imdata(:,i)-imaverage;
end;
clear i imdata
%%
%计算协方差矩阵
%  W=immin*immin';%dxn*nxd =dxd 太大
k=32;
W=immin'*immin; %n*d x d*n= n*n 较小
%计算特征向量与特征值(向量)
[V,~]=eigs(W,k);%降到k维

%对特征向量进行排序
V=immin*V; %dxn*nxk=d*k
VT=fliplr(V);
clear V W


%显示前32个特征脸
 figure;
for i=1:32
    v=VT(:,i);
    %向量矩阵化
    out=reshape(v,112,92); %把(112*92)x1的列向量转成112x92的矩阵
    subplot(4,8,i);
    imshow(out,[]);
    title(strcat('Face',num2str(i)));
end;
clear i v out
%%
%第二步:映射训练集图像到特征空间

%申请训练数据矩阵内存
featuretrain=zeros(k,40*ph);
for i=1:40*ph;
    %映射训练集图像
    add=VT'*immin(:,i);  %k*d x d*1=k*1;
    featuretrain(:,i)=add;
end;
clear i add
%%
%第三步:映射测试集图像到特征空间

%申请录入数据矩阵内存
test=zeros(112*92,40*(10-ph));
for i=1:40    
    for j=(ph+1):10  %3到10
        addr=strcat('G:/orl_face/s',num2str(i),'/',num2str(j),'.pgm');
        a=imread(addr);
        b=a(1:112*92); 
        test(:,(10-ph)*(i-1)+(j-ph))=b';
    end; 
end;

%图像预处理
testmin=zeros(112*92,40*(10-ph));
for i=1:40*(10-ph)     
    testmin(:,i) = test(:,i)-imaverage;
end;
clear i j a b addr test

%申请测试数据矩阵内存
featuretest=zeros(k,40*(10-ph));
for i=1:40*(10-ph);
    %映射测试集图像
    add=VT'*testmin(:,i);
    featuretest(:,i)=add;
end;
clear i add
%%
%匹配计算
count=0;
for t=1:40*(10-ph)
    point=figureNum(featuretest,t,featuretrain,40*ph);
    %计算匹配个数
    if(round(point/ph+0.4)==round(t/(10-ph)+0.4))
        count=count+1;
    end;
end;
tol=count/(40*(10-ph));
clear count point t
display(strcat('匹配率:',num2str(tol*100),'%'));
clear ph tol
toc

figureNum( test,t1,train,num)函数,用于计算最小距离。

function point = figureNum( test,t1,train,num)  
%UNTITLED2 Summary of this function goes here  
%   Detailed explanation goes here  
point=1;  
T=norm(test(:,t1)-train(:,1));%初始默认第一列最匹配  
for t2=1:num  
        distance=norm(test(:,t1)-train(:,t2));  
        if (distance<T)        
            point=t2;        
           T=distance;      
        end;   
end;  
end 

平均脸:
平均脸
特征脸:
32张特征脸

以上使用的是orl人脸库,取每人前6张共40*6张图像作为训练样本,其他的图片作为测试样本,取前32个主成分匹配率是90%.

下面是使用yale库的测试情况,程序只要稍微改一下

%
%测试数据:15人,每人11张照片。每人取前ph张照片作为训练集,后(11-ph)张照片作为测试集。
clear;
clc;
ph=7;
%%
%第一步:计算特征脸并创建特征空间

tic %计算运行时间
%申请录入数据矩阵内存
imdata=zeros(100*100,15*ph);
for i=1:15    
    for j=1:ph  
%         addr=strcat('G:/orl_face/s',num2str(i),'/',num2str(j),'.pgm');
         addr=strcat('G:/yale/s',num2str(i),'/s',num2str(j),'.bmp');
        a=imread(addr);%从地址中读入图像
        b=a(1:100*100); %把图像a矩阵按列顺序转为行向量b
        imdata(:,ph*(i-1)+j)=b'; %把b的转置矩阵存放到imdata矩阵的第ph*(i-1)+j列
    end; 
end;

%计算平均脸
 imaverage=mean(imdata,2); %按行求平均mean(a,2)  按列mean(a)
 %显示平均脸
 %向量矩阵化

    out=reshape(imaverage,100,100);
    figure;
    subplot(1,1,1);
    imshow(out,[]);
    title(strcat('MeanFace'));

clear i j a b addr 

%图像预处理
immin=zeros(100*100,15*ph);
for i=1:15*ph  
    %归一化处理,提升矩阵计算速度,但小数精度不够,会影响匹配率
    %immin(:,i) = (imdata(:,i)-imaverage)/col2medivation(imdata(:,i)-imaverage,112*92);
    %仅减去平均脸,不做归一化处理
    immin(:,i) = imdata(:,i)-imaverage;
end;
clear i imdata
%%
%计算协方差矩阵
% W=immin*immin';%dxn*nxd =dxd 太大
k=20;%k要小于等于ph*15(n)
W=immin'*immin; %n*d x d*n= n*n 较小
%计算特征向量与特征值(向量)
[V,~]=eigs(W,k);%降到k维
%对特征向量进行排序
V=immin*V; %dxn*nxk=d*k
VT=fliplr(V);
clear V W


%显示前20个特征脸
 figure;
for i=1:k
    v=VT(:,i);
    %向量矩阵化
    out=reshape(v,100,100); %把(100*100)x1的列向量转成100x100的矩阵
    subplot(4,5,i);
    imshow(out,[]);
    title(strcat('Face',num2str(i)));
end;
clear i v out 
%%
%第二步:映射训练集图像到特征空间

%申请训练数据矩阵内存
featuretrain=zeros(k,15*ph);
for i=1:15*ph;
    %映射训练集图像
    add=VT'*immin(:,i);  %k*d x d*1=k*1;
    featuretrain(:,i)=add;
end;
clear i add
%%
%第三步:映射测试集图像到特征空间

%申请录入数据矩阵内存
test=zeros(100*100,15*(11-ph));
for i=1:15    
    for j=(ph+1):11  %ph+1到11
        addr=strcat('G:/yale/s',num2str(i),'/s',num2str(j),'.bmp');
        a=imread(addr);
        b=a(1:100*100); 
        test(:,(11-ph)*(i-1)+(j-ph))=b';%把b的转置矩阵存放到test矩阵的第(11-ph)*(i-1)+(j-ph)列
    end; 
end;

%图像预处理
testmin=zeros(100*100,15*(11-ph));
for i=1:15*(11-ph)     
    testmin(:,i) = test(:,i)-imaverage;
end;
clear i j a b addr test

%申请测试数据矩阵内存
featuretest=zeros(k,15*(11-ph));
for i=1:15*(11-ph);
    %映射测试集图像
    add=VT'*testmin(:,i);
    featuretest(:,i)=add;
end;
clear i add
%%
%匹配计算
count=0;
for t=1:15*(11-ph)
    point=figureNum(featuretest,t,featuretrain,15*ph);
    %计算匹配个数
    if(round(point/ph+0.4)==round(t/(11-ph)+0.4))
        count=count+1;
    end;
end;
tol=count/(15*(11-ph));
clear count point t
display(strcat('匹配率:',num2str(tol*100),'%'));
clear ph tol
toc

平均脸
这里写图片描述

特征脸
这里写图片描述

每个人取7张图片作为训练样本,3张作为测试样本,匹配率是86.6667%。

没有更多推荐了,返回首页