
images=[]%([]是什么意思?)
这个只不过是将images初始化为一个空矩阵而已。每度一幅图像,它都将这幅图像reshape成一个列向量,然后存入images中,最终,读了N幅图像,images就有N列,每一列都是一幅图像。
(原算法是有两种方法求特征向量,一种奇异值分解,另一种不用奇异值分解,我这里选用没有用奇异值分解方法,但为什么还是按照奇异值分解了,而且莫名出现一个S的变量,而且这段的公式我不理解)
这个问题是你人脸识别的算法问题,我不想研究。。。。
c=ceil(M/r)%正无穷大方向取整(M/r是什么意思?为什么要这么做)
这个为什么要这么做,是为了后面subplot画图来计算到底需要几行几列的。这个对你的程序没有任何本质的影响。这段程序就是为了把所有的人脸图在一幅图上分块显示出来。从subplot(r,c,ii)
这句可以看出,r子图像的是行数,c是列数。那么M就是图像数了。。。
colormap('gray')axis equal tight off%返回线性灰度色图(这段不理解)
这段是一系列画图参数的 *** 作: colormap('gray')是让你的图是灰度图。axis equal是让横纵坐标单位一致。tight是限制画图的取值范围。off是去掉坐标显示。这些都是控制显示效果的。完全无关紧要。至于具体效果,你可以把这句去掉看看显示效果,然后在加上这句再看看效果有什么变化就知道了。
%对于其他人脸图按前面计算出的特征向量重构人脸图像(这段是说什么?)
很明显的,这个是用你这次这20个训练样本的结果来重构以前的人脸数据。
基本就是这么回事了。但是人脸特征识别我没研究过,你这个程序的算法非常的简单,至于为什么通过几个特征值分析就好用那我就不知道了,因为我没研究过这个。
步骤如下:人脸识别 % FaceRec.m
% PCA 人脸识别修订版,识别率88%
% calc xmean,sigma and its eigen decomposition allsamples=[]%所有训练图像 for i=1:40 for j=1:5
a=imread(strcat('e:\ORL\s',num2str(i),'\',num2str(j),'.jpg'))% imshow(a)
b=a(1:112*92)% b 是行矢量 1×N,其中N=10304,提取顺序是先列后行,即从上 到下,从左到右 b=double(b)
allsamples=[allsamplesb]% allsamples 是一个M * N 矩阵,allsamples 中每一行数 据代表一张图片,其中M=200 end end
samplemean=mean(allsamples)% 平均图片,1 × N
for i=1:200 xmean(i,:)=allsamples(i,:)-samplemean% xmean 是一个M × N 矩阵,xmean 每一行保存的数据是“每个图片数据-平均图片” end
% 获取特征值及特征向量
sigma=xmean*xmean'% M * M 阶矩阵 [v d]=eig(sigma)d1=diag(d)
% 按特征值大小以降序排列 dsort = flipud(d1)vsort = fliplr(v)
%以下选择90%的能量 dsum = sum(dsort)dsum_extract = 0p = 0
while( dsum_extract/dsum <0.9) p = p + 1
dsum_extract = sum(dsort(1:p))end i=1
% (训练阶段)计算特征脸形成的坐标系
base = xmean' * vsort(:,1:p) * diag(dsort(1:p).^(-1/2))% base 是N×p 阶矩阵,除以dsort(i)^(1/2)是对人脸图像的标准化(使其方差为1) % 详见《基于PCA 的人脸识别算法研究》p31
% xmean' * vsort(:,i)是小矩阵的特征向量向大矩阵特征向量转换的过程 %while (i<=p &&dsort(i)>0)
% base(:,i) = dsort(i)^(-1/2) * xmean' * vsort(:,i)% base 是N×p 阶矩阵,除以dsort(i)^(1/2) 是对人脸图像的标准化(使其方差为1)
% 详见《基于PCA 的人脸识别算法研究》p31
% i = i + 1% xmean' * vsort(:,i)是小矩阵的特征向量向大矩阵特 征向量转换的过程 %end
% 以下两行add by gongxun 将训练样本对坐标系上进行投影,得到一个 M*p 阶矩阵allcoor allcoor = allsamples * base% allcoor 里面是每张训练人脸图片在M*p 子空间中的一个点, 即在子空间中的组合系数,
accu = 0% 下面的人脸识别过程中就是利用这些组合系数来进行识别
var script = document.createElement('script')script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'document.body.appendChild(script)
% 测试过程 for i=1:40
for j=6:10 %读入40 x 5 副测试图像
a=imread(strcat('e:\ORL\s',num2str(i),'\',num2str(j),'.jpg'))b=a(1:10304)b=double(b)
tcoor= b * base%计算坐标,是1×p 阶矩阵 for k=1:200
mdist(k)=norm(tcoor-allcoor(k,:))end
%三阶近邻
[dist,index2]=sort(mdist)
class1=floor( (index2(1)-1)/5 )+1class2=floor((index2(2)-1)/5)+1class3=floor((index2(3)-1)/5)+1if class1~=class2 &&class2~=class3 class=class1
elseif class1==class2 class=class1
elseif class2==class3 class=class2end
if class==i accu=accu+1endendend
accuracy=accu/200 %输出识别率
特征人脸 % eigface.m
function [] = eigface()
% calc xmean,sigma and its eigen decomposition allsamples=[]%所有训练图像 for i=1:40 for j=1:5
a=imread(strcat('e:\ORL\s',num2str(i),'\',num2str(j),'.jpg'))% imshow(a)
b=a(1:112*92)% b 是行矢量 1×N,其中N=10304,提取顺序是先列后行,即从上 到下,从左到右 b=double(b)
allsamples=[allsamplesb]% allsamples 是一个M * N 矩阵,allsamples 中每一行数 据代表一张图片,其中M=200 end end
samplemean=mean(allsamples)% 平均图片,1 × N
for i=1:200 xmean(i,:)=allsamples(i,:)-samplemean% xmean 是一个M × N 矩阵,xmean 每一行保存的数据是“每个图片数据-平均图片” end
% 获取特征值及特征向量
sigma=xmean*xmean'% M * M 阶矩阵 [v d]=eig(sigma)d1=diag(d)
% 按特征值大小以降序排列
dsort = flipud(d1)vsort = fliplr(v)
%以下选择90%的能量 dsum = sum(dsort)dsum_extract = 0p = 0
while( dsum_extract/dsum <0.9) p = p + 1
dsum_extract = sum(dsort(1:p))end p = 199
% (训练阶段)计算特征脸形成的坐标系 %while (i<=p &&dsort(i)>0)
% base(:,i) = dsort(i)^(-1/2) * xmean' * vsort(:,i)% base 是N×p 阶矩阵,除以
dsort(i)^(1/2)是对人脸图像的标准化,详见《基于PCA 的人脸识别算法研究》p31 % i = i + 1% xmean' * vsort(:,i)是小矩阵的特征向量向大矩 阵特征向量转换的过程 %end
base = xmean' * vsort(:,1:p) * diag(dsort(1:p).^(-1/2))% 生成特征脸 for (k=1:p),
temp = reshape(base(:,k), 112,92)newpath = ['d:\test\' int2str(k) '.jpg']imwrite(mat2gray(temp), newpath)end
avg = reshape(samplemean, 112,92)
imwrite(mat2gray(avg), 'd:\test\average.jpg')% 将模型保存
save('e:\ORL\model.mat', 'base', 'samplemean')
人脸重建
% Reconstruct.m
function [] = reconstruct() load e:\ORL\model.mat
% 计算新图片在特征子空间中的系数 img = 'D:\test2\10.jpg' a=imread(img)
b=a(1:112*92)% b 是行矢量 1×N,其中N=10304,提取顺序是先列后行,即从上到下, 从左到右 b=double(b)b=b-samplemean
c = b * base% c 是图片a 在子空间中的系数, 是1*p 行矢量 % 根据特征系数及特征脸重建图 % 前15 个 t = 15
temp = base(:,1:t) * c(1:t)'temp = temp + samplemean'
imwrite(mat2gray(reshape(temp, 112,92)),'d:\test2\t1.jpg')% 前50 个 t = 50
temp = base(:,1:t) * c(1:t)'temp = temp + samplemean'
imwrite(mat2gray(reshape(temp, 112,92)),'d:\test2\t2.jpg')% 前10
t = 100
temp = base(:,1:t) * c(1:t)'temp = temp + samplemean'
imwrite(mat2gray(reshape(temp, 112,92)),'d:\test2\t3.jpg')% 前150 个 t = 150
temp = base(:,1:t) * c(1:t)'temp = temp + samplemean'
imwrite(mat2gray(reshape(temp, 112,92)),'d:\test2\t4.jpg')% 前199 个 t = 199
temp = base(:,1:t) * c(1:t)'temp = temp + samplemean'
imwrite(mat2gray(reshape(temp, 112,92)),'d:\test2\t5.jpg')
function []=TwoDPCA
%%%%%%%%%%%%%特征脸显示已正确,训练与测试没有分开。
% Face recognition
clear all
close all
clc
M=200%%%%
traincopy=5%%%表示同一个人有几张相片。
eignum=3%%%选取的特征个数。
cel=cell(1,M)
cellafter=cell(1,M)
tt=clock
S=[]
ii=1
str=strcat('E:\三维人脸\2dfacedatabase\ORL\s1\1.pgm')
img=imread(str)
[ia ib]=size(img)
sum=zeros(ia,ib)
B=zeros(ia,ib)
for i=1:40
for j=1:5
str=strcat('E:\三维人脸\2dfacedatabase\ORL\s',int2str(i),'\',int2str(j),'.pgm')
eval('img=imread(str)')
sum=double(sum)+double(img)
cel{1,ii}=img
ii=ii+1
end
end
meanA=sum/M
cov=zeros(ib)
for i=1:M
img=cel{1,i}
B=double(img)-double(meanA)
temp=B'*B
cov=double(cov)+double(temp)
end
[vv dd]=eig(cov)
num2=size(vv)
% Sort and eliminate those whose eigenvalue is zero
v=[]
d=[]
for i=1:size(vv,2)
if(dd(i,i)>1e-4)
v=[v vv(:,i)]
d=[d dd(i,i)]
end
end
num1=size(v,2)
%sort, will return an ascending sequence
[B index]=sort(d)
ind=zeros(size(index))
dtemp=zeros(size(index))
vtemp=zeros(size(v))
len=length(index)
for i=1:len
dtemp(i)=B(len+1-i)
ind(i)=len+1-index(i)
vtemp(:,ind(i))=v(:,i)
end
d=dtemp
v=vtemp
imgafter=[]
for i=1:M
for j=1:eignum
img=cel{1,i}
temp1=double(img)*double(v(:,j))
imgafter=[imgafter temp1]
end
cellafter{1,i}=imgafter
imgafter=[]
end
timeconsume=etime(clock,tt)
testimg=M/traincopy
findimgnum=traincopy
suc=0
% figure(5)
for k=1:testimg
InputImage =imread(strcat('E:\三维人脸\2dfacedatabase\ORL\s',int2str(k),'\10.pgm'))
testafter=[]
for j=1:eignum
temp=double(InputImage)*double(v(:,j))
testafter=[testafter temp]
end
% Find Euclidean distance
e=[]
for i=1:M
tempA=double(testafter)-double(cellafter{1,i})
total=0
for j=1:eignum
aa=norm(tempA(:,j))
total=total+aa
end
e=[e total]
end
[C index]=sort(e)
min=index(1)
%%%%%%%计算正确率
testingroup=floor((min-1)/traincopy)+1%%计算要测试的图像所在的组
if testingroup==k
suc=suc+1
else
fprintf('%d.jpg fails to match!\n',k)
end
% %%%%%%%%%%%%%%%%%%%显示所有找到的与测试图像为同一个人的图片(可)。(显示所有与测试图片最小距离的那组,而不是比较出来的最小的5个)
% subplot(testimg,findimgnum+1,(k-1)*(findimgnum+1)+1)% subplot(行数,列数,放图像位置的序数)
% imshow(InputImage)
%
% for i=1:findimgnum
% temppos=(testingroup-1)*traincopy+i
% str=strcat('E:\三维人脸\testpic\orl\',int2str(temppos),'.pgm') %concatenates two strings that form the name of the image
% eval('img1=imread(str)')
% subplot(testimg,findimgnum+1,(k-1)*(findimgnum+1)+i+1)
% imshow(img1)
% drawnow
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
sucrate=suc/M*traincopy*100
fprintf('%2.1f%% matched successfully!\n',sucrate)
fprintf('it takes %3.2f S\n',timeconsume)
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)