face.m
上传用户:yzx7066
上传日期:2022-08-04
资源大小:4k
文件大小:11k
源码类别:

图形/文字识别

开发平台:

Matlab

  1. clear all  %删除变量
  2. close all  %关闭窗口
  3. clc        %清除窗口
  4. % 训练的图片数
  5. M=9;
  6. %Chosen std and mean.  选用的标准值和均值
  7. %It can be any number that it is close to the std and mean of most of the images.  
  8. %与大多数图片的标准值和均值相近的数字 如下:
  9. um=100;   %均值
  10. ustd=80;  %标准值
  11. %read and show images(bmp);  读取和显示图片的功能部分:
  12. S=[];   %img matrix     S为图像矩阵.
  13. figure(1);     % 打开figue1
  14. for i=1:M      % 打开已设定的M=9的训练图像
  15.   str=strcat(int2str(i),'.pgm');   %concatenates two strings that form the name of the image
  16.                                    %当前目录里面的1~9.pgm
  17.   eval('img=imread(str);');        %执行字符串         每次循环读入img
  18.   subplot(ceil(sqrt(M)),ceil(sqrt(M)),i)      %ceil 取整   , sqrt 平方根.  在figure1中显示3×3的图像  331,332,333等
  19.   imshow(img)                      %显示图像 
  20.   if i==3
  21.   end
  22.   drawnow;               %更新figure1
  23.   [irow icol]=size(img);   % get the number of rows (N1) and columns (N2)              由img的大小来确定行和列N1,N2
  24.   temp=reshape(img',irow*icol,1);   %creates a (N1*N2)x1 matrix          创造一个N1×N2×1的矩阵
  25.   S=[S temp];       %X is a N1*N2xM matrix after finishing the sequence   
  26.                 %this is our S
  27.         %由读入的图像的行(N1)和列(N2)来定义图像矩阵S的大小
  28. end
  29. %Here we change the mean and std of all images. We normalize all images.
  30. %这部分改变所有的图像的均值和标准值,对图像进行规格化
  31. %This is done to reduce the error due to lighting conditions.
  32. %这样可以降低由光源条件引起的错误
  33. for i=1:size(S,2)                   %size 返回矩阵S的维度
  34.   temp=double(S(:,i));              %双精度
  35.   m=mean(temp);                     %取均值
  36.   st=std(temp);                     %标准偏移
  37.   S(:,i)=(temp-m)*ustd/st+um;       %由此公式对S进行均值化
  38. end
  39. %show normalized images             用figue2显示规格化的图像
  40. figure(2);               
  41. for i=1:M 
  42.   str=strcat(int2str(i),'.bmp');    %读入1~9.bmp文件
  43.   img=reshape(S(:,i),icol,irow);    %重构img
  44.   img=img';                         %转置
  45.   eval('imwrite(img,str)');         %执行字符串
  46.   subplot(ceil(sqrt(M)),ceil(sqrt(M)),i)  %同上 形成3×3的图像排列  
  47.   imshow(img)                       %显示图像
  48.   drawnow;                          %更新figure2
  49.   if i==3
  50.   end
  51. end
  52. %mean image;            均值图像
  53. m=mean(S,2);   %obtains the mean of each row instead of each column    获得行的均值
  54. tmimg=uint8(m);   %converts to unsigned 8-bit integer. Values range from 0 to 255  转换成8位的无符号整数 0~255
  55. img=reshape(tmimg,icol,irow);   %takes the N1*N2x1 vector and creates a N2xN1 matrix   创建一个N2×N1的矩阵
  56. img=img';     %creates a N1xN2 matrix by transposing the image.   对img求转置矩阵
  57. figure(3);                                              %显示均值图像
  58. imshow(img);        
  59. % Change image for manipulation       为处理改变图像
  60. dbx=[];   % A matrix        A矩阵
  61. for i=1:M
  62.   temp=double(S(:,i));           %取双精度
  63.   dbx=[dbx temp];                %将两个矩阵和在一起
  64. end
  65. %Covariance matrix C=A'A, L=AA'     协方差矩阵
  66. A=dbx';                  %由上面得到的dbx的转置矩阵得到矩阵A
  67. L=A*A';                  %A矩阵和A矩阵的转置矩阵的乘积得到L矩阵
  68. % vv are the eigenvector for L                     vv是L的特征向量
  69. % dd are the eigenvalue for both L=dbx'*dbx and C=dbx*dbx';
  70. % dd是L=dbx'*dbx和C=dbx*dbx'的特征值
  71. [vv dd]=eig(L);      %eig函数,用来找到L矩阵的特征值(vv)和特征向量(dd)
  72. % Sort and eliminate those whose eigenvalue is zero         选出并且剔除特征值为0的
  73. v=[];                          %将v置空
  74. d=[];                          %将d置空
  75. for i=1:size(vv,2)   
  76.   if(dd(i,i)>1e-4)             %由此表达式作为衡量标准
  77.     v=[v vv(:,i)];
  78.     d=[d dd(i,i)];
  79.   end
  80. end
  81. %sort, will return an ascending sequence  选出 可以返回降序列的
  82. [B index]=sort(d);                       %sort函数,用来选出上升序列的元素   得到index矩阵,B  因为d为一个矩阵,所以选出d的每一行的升序列
  83. ind=zeros(size(index));                  % ind 与 index同样大的零矩阵
  84. dtemp=zeros(size(index));                % dtemp 同理,也是与index同样大小的零矩阵
  85. vtemp=zeros(size(v));                    % vtemp  与v同样大小的零矩阵
  86. len=length(index);                       % len为index的最大的维数
  87. for i=1:len                              % 从1到len次的循环
  88.   dtemp(i)=B(len+1-i);                   % dtemp(i)的值为B(len+1-i)
  89.   ind(i)=len+1-index(i);                 % ind(i)的值为len+1-index(i)
  90.   vtemp(:,ind(i))=v(:,i);                % vtemp的ind(i)列与v的i列相同
  91. end
  92. d=dtemp;                                 % dtemp值赋给d
  93. v=vtemp;                                 % vtemp值赋给v
  94. %Normalization of eigenvectors               % 特征矢量的规格化
  95. for i=1:size(v,2)     %access each column    访问每一行  
  96.   kk=v(:,i);                                 %将v的第i行赋给kk
  97.   temp=sqrt(sum(kk.^2));                     %取一个临时变量,命名为temp   将kk每一项元素进行平方运算.然后求和,再取平方根 赋给temp
  98.   v(:,i)=v(:,i)./temp;                       %把v矩阵与temp矩阵对应的元素进行相除 再重新生成v
  99. end
  100. %Eigenvectors of C matrix                %矩阵C的特征向量
  101. u=[];                                    %取u为空矩阵
  102. for i=1:size(v,2)                        %访问每一行
  103.   temp=sqrt(d(i));                       %建立一个中间量temp d(i)为d数组中的第i个元素,将其取平方根,赋给temp
  104.   u=[u (dbx*v(:,i))./temp];              %构造矩阵u
  105. end
  106. %Normalization of eigenvectors          特征向量的规格化
  107. for i=1:size(u,2)
  108.   kk=u(:,i);                           %将u的第i列赋给kk
  109.   temp=sqrt(sum(kk.^2));               %取一个临时变量,命名为temp   将kk每一项元素进行平方运算.然后求和,再取平方根 赋给temp
  110.    u(:,i)=u(:,i)./temp;                %把u矩阵与temp矩阵对应的元素进行相除 再重新生成u
  111. end
  112. % show eigenfaces;                     显示特征脸
  113. figure(4);                             %figure4
  114. for i=1:size(u,2)                      
  115.   img=reshape(u(:,i),icol,irow);       %通过u矩阵来重构img
  116.   img=img';                            %将img转置
  117.   img=histeq(img,255);                 %用均衡直方图来提高对比度
  118.   subplot(ceil(sqrt(M)),ceil(sqrt(M)),i)  %在figure4中现实3×3的图像
  119.   imshow(img)                          %show img
  120.   drawnow;                             %更新figure4
  121.   if i==3                       
  122.   end
  123. end
  124. % Find the weight of each face in the training set.           找到每个人脸在训练中的权值
  125. omega = [];                            % 建立一个空矩阵omega
  126. for h=1:size(dbx,2)                    
  127.   WW=[];                               %外层循环建立一个空矩阵WW
  128.   for i=1:size(u,2)
  129.     t = u(:,i)';                       %将u的第i列转置赋给t
  130.     WeightOfImage = dot(t,dbx(:,h)');  %由t和dbx的第h列转置构成向量点,赋给WeightOfImage
  131.     WW = [WW; WeightOfImage];          %构成WW
  132.   end
  133.   omega = [omega WW];                  %构成omega
  134. end
  135. %以上部分即完成了图像的读入,规格化,特征空间的训练,特征脸的形成
  136. %并且显示出训练图像,规格化图像,均值图像和特征脸
  137. %以下部分为识别的部分
  138. % Acquire new image      获得一个新的图像  
  139. % 依旧采用orl脸库中的人脸图像作为试验对象
  140. % 与训练图像保持一致的大小
  141.  
  142. InputImage = input('Please enter the name of the image and its extension n','s');      %输入要读取作为判别的文件
  143. InputImage = imread(strcat(InputImage));                                       %在当前路径下读取文件                    
  144. figure(5)                                                                      %figure5
  145. subplot(1,2,1)                                                                 %在figure 5 中左右显示两个图像
  146. imshow(InputImage); colormap('gray');title('Input image','fontsize',18)        %显示输入的图像,附标题'Input image' 
  147. InImage=reshape(double(InputImage)',irow*icol,1);                              %将输入的图像重构成序列 赋给InImage
  148. temp=InImage;                                                                  %将InImage赋给temp
  149. me=mean(temp);                                                                 %取temp的均值,赋给me
  150. st=std(temp);                                                                  %取temp的标准偏移,赋给st
  151. temp=(temp-me)*ustd/st+um;                                                     %由次表达式处理temp
  152. NormImage = temp;                                                              %将temp赋给NormImage
  153. Difference = temp-m;                                                           %temp与m的差为Difference
  154. NormImage = Difference;                                                        %将Difference赋给NormImage
  155. p = [];                                               %建立一个空矩阵p
  156. aa=size(u,2);                                         %由u的纬度得到aa的值
  157. for i = 1:aa                                          %aa次循环
  158.   pare = dot(NormImage,u(:,i));                       %由NormImage,u的i列构造矢量点pare
  159.   p = [p; pare];                                      %将pare用于构造p矩阵
  160. end
  161. ReshapedImage = m + u(:,1:aa)*p;   %m is the mean image, u is the eigenvector   m为均值图像,u是特征矢量,取u矩阵的1到aa列与p矩阵相乘,再与m相加
  162. ReshapedImage = reshape(ReshapedImage,icol,irow);     %重构ReshapedImage矩阵
  163. ReshapedImage = ReshapedImage';                       %将ReshapedImage转置
  164. %show the reconstructed image.                        现实重构图像
  165. subplot(1,2,2)                                        %在figure5的右边显示重构的图像
  166. imagesc(ReshapedImage); colormap('gray');             %度量ReshapedImage,将它显示出来
  167. title('Reconstructed image','fontsize',18)            %标题:"Reconstructed image"
  168. InImWeight = [];                                      %建立一个空矩阵InImWeight
  169. for i=1:size(u,2)                                     
  170.   t = u(:,i)';                                        %将u的i列转置,赋给t
  171.   WeightOfInputImage = dot(t,Difference');            %构造矢量点WeightOfInputImage
  172.   InImWeight = [InImWeight; WeightOfInputImage];      %构造InImageWeight
  173. end 
  174. ll = 1:M;                                             %
  175. figure(6)                                             
  176. subplot(1,2,1)                                        %figure6左边显示输入图像的权值
  177. stem(ll,InImWeight)                                   %利用stem函数,划分离散序列数据
  178. % Find Euclidean distance                             找到欧几里得距离
  179. e=[];                                                 %建立一个空矩阵e
  180. for i=1:size(omega,2)                     
  181.   q = omega(:,i);                                     %读取omega的第i列
  182.   DiffWeight = InImWeight-q;                          %用InImWeight-q得到DiffWeight
  183.   mag = norm(DiffWeight);                             %得到DiffWeight的范数,赋给mag
  184.   e = [e mag];                                        %构造e矩阵
  185. end
  186.  e
  187. kk = 1:size(e,2);                                     
  188. subplot(1,2,2)                                        %在figure 6 右边显示
  189. stem(kk,e)                                            %划分显示离散序列数据
  190. MaximumValue=max(e)                                   %显示e中的最大值
  191. MinimumValue=min(e)                                   %显示e中的最小值