face.m
上传用户:yzx7066
上传日期:2022-08-04
资源大小:4k
文件大小:11k
- 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
- 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
- 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);
- % 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
- 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; %将InImage赋给temp
- me=mean(temp); %取temp的均值,赋给me
- st=std(temp); %取temp的标准偏移,赋给st
- temp=(temp-me)*ustd/st+um; %由次表达式处理temp
- NormImage = temp; %将temp赋给NormImage
- Difference = temp-m; %temp与m的差为Difference
- NormImage = Difference; %将Difference赋给NormImage
- p = []; %建立一个空矩阵p
- aa=size(u,2); %由u的纬度得到aa的值
- for i = 1:aa %aa次循环
- pare = dot(NormImage,u(:,i)); %由NormImage,u的i列构造矢量点pare
- p = [p; pare]; %将pare用于构造p矩阵
- end
- ReshapedImage = m + u(:,1:aa)*p; %m is the mean image, u is the eigenvector m为均值图像,u是特征矢量,取u矩阵的1到aa列与p矩阵相乘,再与m相加
- ReshapedImage = reshape(ReshapedImage,icol,irow); %重构ReshapedImage矩阵
- ReshapedImage = ReshapedImage'; %将ReshapedImage转置
- %show the reconstructed image. 现实重构图像
- subplot(1,2,2) %在figure5的右边显示重构的图像
- imagesc(ReshapedImage); colormap('gray'); %度量ReshapedImage,将它显示出来
- title('Reconstructed image','fontsize',18) %标题:"Reconstructed image"
- InImWeight = []; %建立一个空矩阵InImWeight
- for i=1:size(u,2)
- t = u(:,i)'; %将u的i列转置,赋给t
- WeightOfInputImage = dot(t,Difference'); %构造矢量点WeightOfInputImage
- InImWeight = [InImWeight; WeightOfInputImage]; %构造InImageWeight
- end
- ll = 1:M; %
- figure(6)
- subplot(1,2,1) %figure6左边显示输入图像的权值
- stem(ll,InImWeight) %利用stem函数,划分离散序列数据
- % Find Euclidean distance 找到欧几里得距离
- e=[]; %建立一个空矩阵e
- for i=1:size(omega,2)
- q = omega(:,i); %读取omega的第i列
- DiffWeight = InImWeight-q; %用InImWeight-q得到DiffWeight
- mag = norm(DiffWeight); %得到DiffWeight的范数,赋给mag
- e = [e mag]; %构造e矩阵
- end
- e
- kk = 1:size(e,2);
- subplot(1,2,2) %在figure 6 右边显示
- stem(kk,e) %划分显示离散序列数据
- MaximumValue=max(e) %显示e中的最大值
- MinimumValue=min(e) %显示e中的最小值