clear all %删除变量
close all %关闭窗口
clc %清除窗口
% 训练的图片数
M=9;
%Chosen std and mean. 选用的标准值和均值
%It can be any number that it is close to the std and mean of most of the images.
%与大多数图片的标准值和均值相近的数字 如下:
um=100; %均值
ustd=80; %标准值
%read and show images(bmp); 读取和显示图片的功能部分:
S=[]; %img matrix S为图像矩阵.
figure(1); % 打开figue1
for i=1:M % 打开已设定的M=9的训练图像
str=strcat(int2str(i),'.pgm'); %concatenates two strings that form the name of the image
%当前目录里面的1~9.pgm
eval('img=imread(str);'); %执行字符串 每次循环读入img
subplot(ceil(sqrt(M)),ceil(sqrt(M)),i) %ceil 取整 , sqrt 平方根. 在figure1中显示3×3的图像 331,332,333等
imshow(img) %显示图像
if i==3
title('Training set','fontsize',18) %标题
end
drawnow; %更新figure1
[irow icol]=size(img); % get the number of rows (N1) and columns (N2) 由img的大小来确定行和列N1,N2
temp=reshape(img',irow*icol,1); %creates a (N1*N2)x1 matrix 创造一个N1×N2×1的矩阵
S=[S temp]; %X is a N1*N2xM matrix after finishing the sequence
%this is our S
%由读入的图像的行(N1)和列(N2)来定义图像矩阵S的大小
end
%Here we change the mean and std of all images. We normalize all images.
%这部分改变所有的图像的均值和标准值,对图像进行规格化
%This is done to reduce the error due to lighting conditions.
%这样可以降低由光源条件引起的错误
for i=1:size(S,2) %size 返回矩阵S的维度
temp=double(S(:,i)); %双精度
m=mean(temp); %取均值
st=std(temp); %标准偏移
S(:,i)=(temp-m)*ustd/st+um; %由此公式对S进行均值化
end
%show normalized images 用figue2显示规格化的图像
figure(2);
for i=1:M
str=strcat(int2str(i),'.bmp'); %读入1~9.bmp文件
img=reshape(S(:,i),icol,irow); %重构img
img=img'; %转置
eval('imwrite(img,str)'); %执行字符串
subplot(ceil(sqrt(M)),ceil(sqrt(M)),i) %同上 形成3×3的图像排列
imshow(img) %显示图像
drawnow; %更新figure2
if i==3
title('Normalized Training Set','fontsize',18)
end
end
%mean image; 均值图像
m=mean(S,2); %obtains the mean of each row instead of each column 获得行的均值
tmimg=uint8(m); %converts to unsigned 8-bit integer. Values range from 0 to 255 转换成8位的无符号整数 0~255
img=reshape(tmimg,icol,irow); %takes the N1*N2x1 vector and creates a N2xN1 matrix 创建一个N2×N1的矩阵
img=img'; %creates a N1xN2 matrix by transposing the image. 对img求转置矩阵
figure(3); %显示均值图像
imshow(img);
title('Mean Image','fontsize',18)
% Change image for manipulation 为处理改变图像
dbx=[]; % A matrix A矩阵
for i=1:M
temp=double(S(:,i)); %取双精度
dbx=[dbx temp]; %将两个矩阵和在一起
end
%Covariance matrix C=A'A, L=AA' 协方差矩阵
A=dbx'; %由上面得到的dbx的转置矩阵得到矩阵A
L=A*A'; %A矩阵和A矩阵的转置矩阵的乘积得到L矩阵
% vv are the eigenvector for L vv是L的特征向量
% dd are the eigenvalue for both L=dbx'*dbx and C=dbx*dbx';
% dd是L=dbx'*dbx和C=dbx*dbx'的特征值
[vv dd]=eig(L); %eig函数,用来找到L矩阵的特征值(vv)和特征向量(dd)
% Sort and eliminate those whose eigenvalue is zero 选出并且剔除特征值为0的
v=[]; %将v置空
d=[]; %将d置空
for i=1:size(vv,2)
if(dd(i,i)>1e-4) %由此表达式作为衡量标准
v=[v vv(:,i)];
d=[d dd(i,i)];
end
end
%sort, will return an ascending sequence 选出 可以返回降序列的
[B index]=sort(d); %sort函数,用来选出上升序列的元素 得到index矩阵,B 因为d为一个矩阵,所以选出d的每一行的升序列
ind=zeros(size(index)); % ind 与 index同样大的零矩阵
dtemp=zeros(size(index)); % dtemp 同理,也是与index同样大小的零矩阵
vtemp=zeros(size(v)); % vtemp 与v同样大小的零矩阵
len=length(index); % len为index的最大的维数
for i=1:len % 从1到len次的循环
dtemp(i)=B(len+1-i); % dtemp(i)的值为B(len+1-i)
ind(i)=len+1-index(i); % ind(i)的值为len+1-index(i)
vtemp(:,ind(i))=v(:,i); % vtemp的ind(i)列与v的i列相同
end
d=dtemp; % dtemp值赋给d
v=vtemp; % vtemp值赋给v
%Normalization of eigenvectors % 特征矢量的规格化
for i=1:size(v,2) %access each column 访问每一行
kk=v(:,i); %将v的第i行赋给kk
temp=sqrt(sum(kk.^2)); %取一个临时变量,命名为temp 将kk每一项元素进行平方运算.然后求和,再取平方根 赋给temp
v(:,i)=v(:,i)./temp; %把v矩阵与temp矩阵对应的元素进行相除 再重新生成v
end
%Eigenvectors of C matrix %矩阵C的特征向量
u=[]; %取u为空矩阵
for i=1:size(v,2) %访问每一行
temp=sqrt(d(i)); %建立一个中间量temp d(i)为d数组中的第i个元素,将其取平方根,赋给temp
u=[u (dbx*v(:,i))./temp]; %构造矩阵u
end
%Normalization of eigenvectors 特征向量的规格化
for i=1:size(u,2)
kk=u(:,i); %将u的第i列赋给kk
temp=sqrt(sum(kk.^2)); %取一个临时变量,命名为temp 将kk每一项元素进行平方运算.然后求和,再取平方根 赋给temp
u(:,i)=u(:,i)./temp; %把u矩阵与temp矩阵对应的元素进行相除 再重新生成u
end
% show eigenfaces; 显示特征脸
figure(4); %figure4
for i=1:size(u,2)
img=reshape(u(:,i),icol,irow); %通过u矩阵来重构img
img=img'; %将img转置
img=histeq(img,255); %用均衡直方图来提高对比度
subplot(ceil(sqrt(M)),ceil(sqrt(M)),i) %在figure4中现实3×3的图像
imshow(img) %show img
drawnow; %更新figure4
if i==3
title('Eigenfaces','fontsize',18) % 显示'Eigenfaces'
end
end
% Find the weight of each face in the training set. 找到每个人脸在训练中的权值
omega = []; % 建立一个空矩阵omega
for h=1:size(dbx,2)
WW=[]; %外层循环建立一个空矩阵WW
for i=1:size(u,2)
t = u(:,i)'; %将u的第i列转置赋给t
WeightOfImage = dot(t,dbx(:,h)'); %由t和dbx的第h列转置构成向量点,赋给WeightOfImage
WW = [WW; WeightOfImage]; %构成WW
end
omega = [omega WW]; %构成omega
end
%以上部分即完成了图像的读入,规格化,特征空间的训练,特征脸的形成
%并且显示出训练图像,规格化图像,均值图像和特征脸
%以下部分为识别的部分
% Acquire new image 获得一个新的图像
% 依旧采用orl脸库中的人脸图像作为试验对象
% 与训练图像保持一致的大小
InputImage = input('Please enter the name of the image and its extension \n','s'); %输入要读取作为判别的文件
InputImage = imread(strcat(InputImage)); %在当前路径下读取文件
figure(5) %figure5
subplot(1,2,1) %在figure 5 中左右显示两个图像
imshow(InputImage); colormap('gray');title('Input image','fontsize',18) %显示输入的图像,附标题'Input image'
InImage=reshape(double(InputImage)',irow*icol,1); %将输入的图像重构成序列 赋给InImage
temp=InImage;
评论0