%PCA+DCT+2DPCA
im=20;%先用20张图片测试,之后要用200张图片实验
%train_img=7;%表示读入一个人的7张图片,其中包括训练图片01,图片02-07用来做测试
allfaces=[];
allgrayfaces=[];
%多个人的人脸图片
l=1;%表示读入人脸的第一张图片,作为训练集
%应用2D-DCT时,变换矩阵C, 对重建图像进行DCT变换
%tic
img=imread(strcat('F:\单样本识别\ORL\FERET-001\01.tif'));
X=double(img);
M=size(X,1);
N=size(X,2);
%Y=zeros(M,N);
%M=80;
Cm=zeros(M,M);
Cn=zeros(N,N);
%C(:,1)=1/sqrt(M);
for k=1:M
for m=1:M
if k==1
Cm(m,k)=1/sqrt(M)*cos(pi*(2*m+1)*k/(2*M));
else
Cm(m,k)=sqrt(2)/sqrt(M)*cos(pi*(2*m+1)*k/(2*M));
end
end
end
for m=1:N
for k=1:N
if m==1
Cn(m,k)=1/sqrt(N)*cos(pi*(2*k+1)*m/2/N);
else
Cn(m,k)=sqrt(2)/sqrt(N)*cos(pi*(2*k+1)*m/2/N);
end
end
end
%Y=Cm'*X*Cn';
%M和N表示DCT的逆变换后的维度,即提取的DCT系数
p=50;
M=p;
N=p;
Dm=zeros(M,p);
Dn=zeros(p,N);
for x=1:p
for u=1:M
if u==1
Dm(u,x)=1/sqrt(M)*cos((2*x+1)*u*pi/2/M);
else
Dm(u,x)=sqrt(2)/sqrt(M)*cos((2*x+1)*u*pi/2/M);
end
end
end
for y=1:p
for v=1:N
if v==1
Dn(y,v)=1/sqrt(N)*cos((2*y+1)*v*pi/2/N);
else
Dn(y,v)=sqrt(2)/sqrt(N)*cos((2*y+1)*v*pi/2/N);
end
end
end
%X=Dm'*Y(1:M,1:N)*Dn';
%imwrite(mat2gray(Y),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\人脸重建FERET-001-02.tif'));
%imwrite(mat2gray(X),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\人脸重建FERET-001-002-20.tif'));
%toc
allsamples=[]; %所有训练图像
xmean=[];
%% 训练样本应用PCA重建人脸图像,再用DCT
for i=1:im%先用20张图片做实验
if i<10
img=imread(strcat('F:\单样本识别\ORL\FERET-00',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-001~FERET-009的第一张人脸图片01.tif
else
if i<100
img=imread(strcat('F:\单样本识别\ORL\FERET-0',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-010~FERET-099的第一张人脸图片01.tif
else
img=imread(strcat('F:\单样本识别\ORL\FERET-',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-100~FERET-200的第一张人脸图片01.tif
end
end
b=img( 1:80*80 ); % b是行矢量 1×N,其中N=80*80=6400,提取顺序是先列后行,即从上到下,从左到右
b=double(b);
allsamples=[ allsamples; b ]; % allsamples是一个M*N 矩阵,allsamples中每一行数据代表一张图片,其中M=20
fprintf('读入第 %d 个人的第 %d 张人脸图片\n',i,l);
end
samplemean=mean(allsamples); % 平均图片,1 × N
for i=1:im
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 = 0;
p1 = 0;
while( dsum_extract/dsum < 0.9)
p1 = p1+ 1;
dsum_extract = sum(dsort(1:p1));
end
i=1;
% (训练阶段)计算特征脸形成的坐标系
base = xmean' * vsort(:,1:p1) * diag(dsort(1:p1).^(-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)
% i = i + 1; % xmean' * vsort(:,i)是小矩阵的特征向量向大矩阵特征向量转换的过程
% end
% 将训练样本对坐标系上进行投影,得到一个 M*p 阶矩阵allcoor
allcoor = allsamples * base; % allcoor 里面是每张训练人脸图片在 M*p 子空间中的一个点,即在子空间中的组合系数,
%利用PCA算法rebuild face images
% 根据特征系数及特征脸重建图( p=6 : 6个特征脸,即:6个特征值和特征向量)
c=xmean*base;
allsamples=[];
a_allsamples=[];
t=6;
for i=1:im
temp=base(:,1:t)*c(i,1:t)';
% temp=base(:,1:t)*allcoor(i,1:t)';
temp=temp+samplemean';
allfaces=[allfaces;reshape(temp,80,80)];
imwrite(mat2gray(reshape(temp, 80,80)),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\rebuildfaces\人脸重建',num2str(i),'.tif'));
allgrayfaces=[allgrayfaces;mat2gray(reshape(temp, 80,80))];
%DCT变换的一幅人脸图片
DCTface=Cm'*reshape(temp,80,80)*Cn';
imwrite(mat2gray(DCTface),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\1人脸重建0',num2str(i),'.tif'));
%DCT逆变换的一幅人脸图片
NDCTface=Dm'*DCTface(1:p,1:p)*Dn';
imwrite(mat2gray(NDCTface),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\1人脸重建',num2str(i),'.tif'));
allsamples=[allsamples;NDCTface];
a_allsamples=[a_allsamples;reshape(NDCTface,1,p*p)];
end
%% 直接对人脸图像用DCT
% a_allsamples=[];
% for i=1:im%先用20张图片做实验
% if i<10
% img=imread(strcat('F:\单样本识别\ORL\FERET-00',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-001~FERET-009的第一张人脸图片01.tif
% else
% if i<100
% img=imread(strcat('F:\单样本识别\ORL\FERET-0',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-010~FERET-099的第一张人脸图片01.tif
% else
% img=imread(strcat('F:\单样本识别\ORL\FERET-',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-100~FERET-200的第一张人脸图片01.tif
% end
% end
% % b=img( 1:80*80 ); % b是行矢量 1×N,其中N=80*80=6400,提取顺序是先列后行,即从上到下,从左到右
% b=double(img);
% DCTface=Cm'*b*Cn';
% imwrite(mat2gray(DCTface),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\2人脸重建0',num2str(i),'.tif'));
% %DCT逆变换的一幅人脸图片
% NDCTface=Dm'*DCTface(1:p,1:p)*Dn';
% imwrite(mat2gray(NDCTface),strcat('F:\单样本识别\【matlab】单样本PCA+2DPCA人脸识别代码\DCT重建人脸\2人脸重建',num2str(i),'.tif'));
% allsamples=[allsamples;NDCTface];
% a_allsamples=[a_allsamples;reshape(NDCTface,1,p*p)];
%
% %allsamples=[ allsamples; b ]; % allsamples是一个M*N 矩阵,allsamples中每一行数据代表一张图片,其中M=20
%
% fprintf('读入第 %d 个人的第 %d 张人脸图片\n',i,l);
% end
%%
a_samplemean=mean(a_allsamples);
a_samplemean=reshape(a_samplemean,size(a_samplemean,1)*p,p);%得到训练样本--人脸平均矩阵A,为80*80维的
xmean=[];
sigma=zeros(p,p);
for i=0:(im-1)
xmean=allsamples(i*p+1:i*p+p,:)-a_samplemean;
sigma=sigma+xmean'*xmean;
end
sigma=sigma/im;
% % 获取特征值及特征向量
% sigma=xmean*xmean'; % M * M 阶矩阵
[v d]=eig(sigma);
d1=diag(d);
% 按特征值大小以降序排列
dsort = flipud(d1);
vsort = fliplr(v);
%以下选择60%的能量
dsum = sum(dsort);
dsum_extract = 0;
p1 = 0;
while( dsum_extract/dsum < 0.5)
p1 = p1 + 1;
dsum_extract = sum(dsort(1:p1));
end
i=1;
% (训练阶段)计算特征脸形成的坐标系
%base = xmean' * vsort(:,1:p) * diag(dsort(1:p).^(-1/2));
base1 = vsort(:,1:p1) * diag(dsort(1:p1).^(-1/2));
allcoor1 = allsamples * base1; % allcoor 里面是每张训练人脸图片在 M*p 子空间中的一个点,即在子空间中的组合系数,
accu = 0; % 下面的人脸识别过程中就是利用这些组合系数来进行识别
%%
% 测试过程
%alltest=[]; %所有测试图像
test_img=7;%表示读入一个人的6张图片,其中包括训练图片02-07用来做测试
mdist=[];
%多个人的人脸图片
%l=1;%表示读入人脸的第一张图片,作为训练集
for l=2:test_img
for i=1:im%先用20张图片做实验
if i<10
img=imread(strcat('F:\单样本识别\ORL\FERET-00',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-001~FERET-009的第一张人脸图片01.tif
else
if i<100
img=imread(strcat('F:\单样本识别\ORL\FERET-0',num2str(i),'\0',num2str(l),'.tif'));%读文件夹FERET-010~FERET-099的第一张人脸图片01.tif
else
img=imread