基于matlab简单的特征脸的人脸识别程序

基于matlab简单的特征脸的人脸识别程序,第1张

这是我写的程序,参照《模式识别》张学工第9章。

a1=imread('a1.jpg')

a2=imread('a2.jpg')

b1=imread('b1.jpg')

b2=imread('b2.jpg')

a1=rgb2gray(a1)

a2=rgb2gray(a2)

b1=rgb2gray(b1)

b2=rgb2gray(b2)

figure,imshow(a1)

figure,imshow(a2)

figure,imshow(b1)

figure,imshow(b2)

a1=double(a1)

a2=double(a2)

b1=double(b1)

b2=double(b2)

a1_lie=a1(:)

a2_lie=a2(:)

b1_lie=b1(:)

b2_lie=b2(:)

c=cat(1,a1_lie',a2_lie',b1_lie',b2_lie')

c_mean=mean(c)

X=[a1_lie-c_mean',a2_lie-c_mean',b1_lie-c_mean',b2_lie-c_mean']

R=X'*X % R是4×4的矩阵

[p,q]=eig(R)

u=diag(q) % u是4×1的列向量

u=flipud(u) % flipud(u)实现矩阵的上下翻转, u是4×1的列向量

v=fliplr(p) % fliplr(p)实现矩阵的左右翻转,v是4×4的矩阵

e=zeros(36000,4)

for m=1:3

e(:,m)=X*v(:,m)./(u(m)^(-0.5)) % 参见《模式识别》P226公式9-18

end

p1=zeros(200,180)

p2=zeros(200,180)

p3=zeros(200,180)

for m=1:36000

p1(m)=e(m)

p2(m)=e(m+36000)

p3(m)=e(m+72000)

end

p1=mat2gray(p1)

p2=mat2gray(p2)

p3=mat2gray(p3)

figure,imshow(p1) % 显示第1特征

figure,imshow(p2) % 显示第2特征脸

figure,imshow(p3) % 显示第3特征脸

new=c*e(:,1:3) %分别计算4个训练样本分别在第1、第2、第3、特征脸上的投影

p1=imread('p_test1.jpg')%读入一个测试样本

p1=rgb2gray(p1)

figure,imshow(p1)

p2=double(p1(:))

test=p2'*e(:,1:3)%计算测试样本在3个特征脸上的投影

error=zeros(4,1)

for m=1:4

error(m)=norm((new(m,:)-test))

end

[distence,index]=sort(error) %将列向量error中的数据按从小到大排列

if index(1)==1

result=1

elseif index(1)==2

result=1

elseif index(1)==3

result=2

elseif index(1)==4

result=2

end

result %result为1时表示测试样本属于第1个人,为2时表示测试样本属于第2个人

步骤如下:

人脸识别 % 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)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7737065.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存