matlab实现人脸识别---PCA与最近邻法

来源:互联网 发布:数据库安全性设计 编辑:程序博客网 时间:2024/06/06 17:21

目标:已知类别的人脸图像,待检类别图像,从待检测图像中识别与已知类别的图像中相同的图像。

已知类别:3479张

待检测类别:276张

PCA给样本矩阵降维

最近邻法识别

一共包括3个.m文件,train.m,test.m,recognition.m。

train.m文件实现将训练样本矩阵降维,并得到映射矩阵;test.m文件将测试样本矩阵降维;recognition.m文件实现识别过程。

train.m代码:

file_path='F:\课程\模式识别\Dataset\muct人脸图像\已知类别\';% 图像文件夹路径 img_path_list = dir(strcat(file_path,'*.jpg'));%获取该文件夹中所有jpg格式的图像img_num = length(img_path_list);%获取图像总数量imgTrain = [];Q = [];%列矩阵,一副图像trainFace = [];%降维后的训练样本的矩阵% 读取每一幅图像%转化为灰度图像 并将每一幅图像转化为列向量 然后合并为矩阵Tfor j=1:img_num %逐一读取图像    image_name = img_path_list(j).name;%图像名    img = imread(strcat(file_path,image_name));                  img = rgb2gray(img);%转为灰度       %img=histeq(img);%直方图均衡化    img=imadjust(img);%使得图像中 1% 的数据饱和至最低和最高亮度    img = imresize(img, 0.2, 'nearest');     [irow,icol] = size(img);%得到图片大小%     for m=1:irow%         for n=1:icol%             img(m,n) = 10*img(m,n);%         end%     end    temp = reshape(img,irow*icol,1);%将二维图片转为一维向量    Q = [Q,temp]; % 每张图片的信息做为V的一列      imgTrain=[imgTrain,temp];   end%  [L_eig_vec,A] = HSCalPCA(imgTrain);%调用PCA降维函数,得到映射矩阵%得到均值矩阵%并用T剪去均值矩阵  得到矩阵A m = mean(imgTrain,2); % 平均图像/行平均(每一副图像的对应象素求平均)m=(1/P)*sum(Tj's) (j=1 : P)Train_Number = size(imgTrain,2);%列数%计算机每一张图片到均值图像的方差A = [];  for i = 1 : Train_Number%对每一列    temp = double(imgTrain(:,i))-m; %每一张图与均值的差异    A = [A temp]; %差矩阵end%得到A的协方差矩阵并转置得到LL = A'*A; % L是协方差矩阵C=A*A'的转置%得到特征值与特征向量[V D] = eig(L); %对角线上的元素是L|C的特征值.V:以特征向量为列的满秩矩阵,D:特征值对角矩阵。即L*V = V*D.L_eig_vec = [];%特征值向量max=0;for i = 1 : size(V,2)%对每个特征向量      max=max+D(i,i);endsum=0;for i = size(V,2):-1:size(V,2)-2%对每个特征向量          L_eig_vec = [L_eig_vec V(:,i)]*0;%集中对应的特征向量    sum=sum+D(i,i);endfor i = size(V,2)-3:-1:size(V,2)-9%对每个特征向量          L_eig_vec = [L_eig_vec V(:,i)]*0.05;%集中对应的特征向量    sum=sum+D(i,i);endfor i = size(V,2)-10:-1:1%对每个特征向量          L_eig_vec = [L_eig_vec V(:,i)];%集中对应的特征向量    sum=sum+D(i,i);    if(sum/max>0.99)        break;    endend% for i = 1:size(V,2)%      if(D(i,i)>1)% L_eig_vec = [L_eig_vec V(:,i)];%     end% endEigenfaces = A * L_eig_vec; % 计算机协方差矩阵C的特征向量,                            %得到降维了的特征,A为每一张图像与均值图像的方差构成的矩阵,TrainProjectedImages = [];%映射图像for i = 1 : img_num%对于每一个训练特征    temp = Eigenfaces'*double(Q(:,i));    TrainProjectedImages = [TrainProjectedImages temp];  %得到 L_eig_vec;endsave('D:\Program Files\MATLAB\R2016a\bin\projects\face1\TrainProjectedImages.mat','TrainProjectedImages');save('D:\Program Files\MATLAB\R2016a\bin\projects\face1\Eigenfaces.mat','Eigenfaces');


test.m:

TrainProjectedImages=load('D:\Program Files\MATLAB\R2016a\bin\projects\face1\TrainProjectedImages.mat');TrainProjectedImages=TrainProjectedImages.TrainProjectedImages;%训练数据集(降维后的) Eigenfaces=load('D:\Program Files\MATLAB\R2016a\bin\projects\face1\Eigenfaces.mat');Eigenfaces=Eigenfaces.Eigenfaces;%训练数据集(降维后的) % imgTrain=load('D:\Program Files\MATLAB\R2016a\bin\projects\face1\imgTrain.mat');% imgTrain=imgTrain.imgTrain;%训练数据集(降维后的)file_path='F:\课程\模式识别\Dataset\muct人脸图像\待分类\';% 图像文件夹路径 img_path_list = dir(strcat(file_path,'*.jpg'));%获取该文件夹中所有jpg格式的图像img_num = length(img_path_list);%获取图像总数量imgTest = [];Q = [];%列矩阵,一幅图像testFace = [];%减去训练矩阵均值后的测试图像矩阵%导入由训练数据集得到的  变换矩阵跟降维后的训练集% 读取每一幅图像%转化为灰度图像 并将每一幅图像转化为列向量 然后合并为矩阵Tfor j=1:img_num %逐一读取图像    image_name = img_path_list(j).name;%图像名    img = imread(strcat(file_path,image_name));                  img = rgb2gray(img);%转为灰度       %img=histeq(img);%直方图均衡化    img=imadjust(img);%使得图像中 1% 的数据饱和至最低和最高亮度     img = imresize(img, 0.2, 'nearest');%改变图像的大小,'nearest'(默认值)最近邻插值    [irow,icol] = size(img);%得到图片大小%     for m=1:irow%         for n=1:icol%             img(m,n) = 10*img(m,n);%         end%     end    temp = reshape(img,irow*icol,1);%将二维图片转为一维向量    Q = [Q,temp]; % 每张图片的信息做为V的一列         imgTest = [imgTest,temp];   end%     imgTrain = imgTrain';%     mMiu = mean(imgTrain,2);%求各行的均值%     %     mMiu = repmat(mMiu,1,icol);%复制成原有的行数N列的矩阵%     testFace =double(imgTest')-mMiu;TestProjectedImages = [];%测试集降维for i = 1 : img_num%对于每一个训练特征    temp = Eigenfaces'*double(Q(:,i));    TestProjectedImages = [TestProjectedImages temp];  %得到 L_eig_vec;end% TsetProjectedImages1=trainFace*double(testFace' );  save('D:\Program Files\MATLAB\R2016a\bin\projects\face1\TestProjectedImages.mat','TestProjectedImages');% save('D:\Program Files\MATLAB\R2016a\bin\projects\face\testFace.mat','testFace');


recognition.m:
clc;clear;m=0;count=0;% 加载降维后的样本和测试矩阵,进行最近邻法识别TrainProjectedImages=load('D:\Program Files\MATLAB\R2016a\bin\projects\face1\TrainProjectedImages.mat');TrainProjectedImages=TrainProjectedImages.TrainProjectedImages;%训练数据集(降维后的) *3479TestProjectedImages=load('D:\Program Files\MATLAB\R2016a\bin\projects\face1\TestProjectedImages.mat');TestProjectedImages=TestProjectedImages.TestProjectedImages;%测试数据集(降维后的)    *276[Trainrows,Traincols] = size(TrainProjectedImages);%得到训练集的大小[Testrows,Testcols] = size(TestProjectedImages);%得到测试集的大小%将训练图片的名字存到以为矩阵里img_name_train = [];img_name_test = [];file_path_train= 'F:\课程\模式识别\Dataset\muct人脸图像\已知类别\';img_path_list_train = dir(strcat(file_path_train,'*.jpg'));img_num_train = length(img_path_list_train);% for k=1:img_num_train% name2 = img_path_list_train(k).name;%     img_name_train = [img_name_train,name2];% end%将测试图片的名字存到一维矩阵里file_path_test= 'F:\课程\模式识别\Dataset\muct人脸图像\待分类\';img_path_list_test = dir(strcat(file_path_test,'*.jpg'));img_num_test = length(img_path_list_test);% for g=1:img_num_test% name1= img_path_list_test(g).name;%     img_name_test = [img_name_test,name1];% end%循环,计算每张测试图片与训练图片的距离,找到距离最小的测试图,判断测试图片与训练图片名字是否一致,一致数量加一for i=1:Testcols    mImgTestCur = TestProjectedImages(:,i);    vDisMin = 9999999999999;    vClassMin = -1;    for j=1:Traincols        mImgTrainCur = TrainProjectedImages(:,j);        mDis = mImgTestCur-mImgTrainCur;        mDis = mDis.^2;        vDis = sqrt(sum(mDis));        if vDis<vDisMin            vDisMin = vDis;    m=j;        end    end    name1=img_path_list_train(m).name;   name1 =name1(2:4);%取名字的第2到4位置的字符   name1=str2num(name1);    name2=img_path_list_test(i).name;     name2 =name2(2:4);      name2=str2num(name2);    if name2==name1count=count+1;    end       endvRatio = count/Testcols*100;sprintf('正确率:%.1f%%',vRatio)


原创粉丝点击