a=input('請(qǐng)輸入你需要提取的特征維數(shù)(僅限于8, 16超凳,24, 32愈污,48,64轮傍,80):');
for featureNumber =[a]%[8, 16,24, 32, 48, 64, 80]; % 特征維數(shù)暂雹,僅限于8, 16,24, 32创夜,48杭跪,64,80
%% 1.參數(shù)配置
save featureNumber featureNumber ;
clear all; close all; warning off; format compact;%rng('default');
load featureNumber ;
disp('##################################################');
disp(['----------------','featureNumber=',num2str(featureNumber ),'時(shí)','----------------']);
%% 2.圖片分塊并計(jì)算每塊的最大奇異值驰吓,并構(gòu)成每張圖片的特征向量
num=1;
%得出圖片的路徑揍魂,并自動(dòng)讀入每張圖片
dir = ['_1.bmp ';'_2.bmp ';'_3.bmp ';'_4.bmp '; '_5.bmp ';'_6.bmp '; '_7.bmp ';'_8.bmp ';'_9.bmp '; '_10.bmp'];
for x=1:40
%將數(shù)字轉(zhuǎn)換成字符,便于把兩個(gè)字符連接棚瘟,組成圖片的完整路徑
a = int2str(x);
b = ['s'];
d = [b a];
for i=1:10
%得到每張圖片的文件名
e = [d dir(i,1:7)];
% 將圖片轉(zhuǎn)化成為灰度矩陣
M = double(imread(e));
%如果用戶輸入的是8,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到8維的特征向量
if (featureNumber == 8)
for j=1:4
for k=1:2
%將圖片的灰度矩陣劃分成8塊小矩陣
temp=M((j-1)*28+1:j*28,(k-1)*46+1:k*46);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取一個(gè)的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*2+k)=temp2;
end
end
end
%如果用戶輸入的是16,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到16維的特征向量
if (featureNumber == 16)
for j=1:4
for k=1:4
%將圖片的灰度矩陣劃分成16塊小矩陣
temp=M((j-1)*28+1:j*28,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果用戶輸入的是24,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到16維的特征向量
if (featureNumber == 24)
for j=1:6
for k=1:4
%將圖片的灰度矩陣劃分成24塊小矩陣
temp=M((j-1)*18+1:j*18,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果用戶輸入的是32,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到32維的特征向量
if (featureNumber == 32)
for j=1:8
for k=1:4
%將圖片的灰度矩陣劃分成32塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果用戶輸入的是48,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到48維的特征向量
if (featureNumber == 48)
for j=1:8
for k=1:6
%將圖片的灰度矩陣劃分成48塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*15+1:k*15);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*6+k)=temp2;
end
end
end
%如果用戶輸入的是64,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到64維的特征向量
if (featureNumber == 64)
for j=1:8
for k=1:8
%將圖片的灰度矩陣劃分成64塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*11+1:k*11);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
feature((x-1)*10+i,(j-1)*8+k)=temp2;
end
end
end
%如果用戶輸入的是80,則執(zhí)行下段代碼,把數(shù)據(jù)處理得到80維的特征向量
if (featureNumber == 80)
for j=1:10
for k=1:8
temp=M((j-1)*11+1:j*11,(k-1)*11+1:k*11);%將圖片的灰度矩陣劃分成80塊小矩陣
[u,temp1,v]=svd(temp);%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
temp2=temp1(num,num);%提取最大的SVD系數(shù)作為特征值
feature((x-1)*10+i,(j-1)*8+k)=temp2;%得到所有圖片的特征矩陣
end
end
end
end
end
tag=0;
for x=1:40
%將數(shù)字轉(zhuǎn)換成字符现斋,便于把兩個(gè)字符連接,組成圖片的完整路徑
a = int2str(x);
b = ['s'];
d = [b a];
for i=1:10
tag=tag+1;
%得到每張圖片的文件名
e = [d dir(i,1:7)];
%將圖片轉(zhuǎn)化成為灰度矩陣
M = double(imread(e));
picture(tag,:)=reshape(M,1,92*112);
end
end
%% 3.屬于預(yù)處理(包括劃分訓(xùn)練集和測(cè)試集, 數(shù)據(jù)歸一化處理等)
num_train=8; %這里我們?cè)O(shè)置的每一類數(shù)據(jù)大小為10, 所以num_train的大小為1~10.
feature=feature'; %進(jìn)行矩陣倒置偎蘸,因?yàn)樵撍惴ㄒ缶仃嚨男袛?shù)比列數(shù)少
num_test=10-num_train;
for y=1:40 %構(gòu)造訓(xùn)練集,一共有40個(gè)人庄蹋,每人10張圖片
for n=1:num_train
train_data(:,(y-1)*num_train + n) = feature(:,(y-1)*10 + n); %構(gòu)造訓(xùn)練集
train_picture((y-1)*num_train + n,:) = picture((y-1)*10 + n,:);
end
for z=1:num_test
test_data(:,(y-1)*num_test+z)= feature(:,(y-1)*10 +num_train+z);%構(gòu)造測(cè)試集
test_picture((y-1)*num_test+z, :)= picture((y-1)*10 +num_train+z,:);
end
end
for y=1:40
for m=1:num_train
t(y,(y-1)*num_train+m)=1;%構(gòu)造訓(xùn)練集目標(biāo)集
end
end
max_train=max(train_data(:));
min_train=min(train_data(:));
pn = mat2gray(train_data,[min_train ,max_train]);%對(duì)訓(xùn)練集數(shù)據(jù)進(jìn)行歸一化處理
pnewn = mat2gray(test_data,[min_train ,max_train]);%對(duì)測(cè)試集數(shù)據(jù)進(jìn)行歸一化處理
%% 4.訓(xùn)練BP神經(jīng)網(wǎng)絡(luò)
%調(diào)用MATLAB神經(jīng)網(wǎng)絡(luò)工具箱瞬内,構(gòu)建BP神經(jīng)網(wǎng)絡(luò)
net = newff(minmax(pn),[110,40],{'tansig','purelin'},'trainrp');
% 函數(shù)newff建立一個(gè)可訓(xùn)練的前饋網(wǎng)絡(luò)。
% (1) 函數(shù)功能:訓(xùn)練前饋網(wǎng)絡(luò)的第一步是建立網(wǎng)絡(luò)對(duì)象限书。
% 輸入?yún)?shù)說明:
% 100表示: 輸入隱含層神經(jīng)元個(gè)數(shù)
% 40表示: 輸出層的個(gè)數(shù)(40個(gè)人的人臉,即40類)
% 'tansig'表示: 輸入層與隱含層之間的傳遞函數(shù)
% 'purelin'表示: 隱含層與輸出層之間的傳遞函數(shù)
% 'trainrp'表示: BP網(wǎng)絡(luò)訓(xùn)練函數(shù)(有彈回的BP算法,用于消除梯度模值對(duì)網(wǎng)絡(luò)訓(xùn)練帶來的影響,提高訓(xùn)練的速度)
net.trainParam.goal=1e-5;%訓(xùn)練目標(biāo)
net.trainParam.epochs=10000;%訓(xùn)練次數(shù)
net.trainParam.lr = 0.005;%學(xué)習(xí)速率
[net,tr] = train(net,pn,t); % 訓(xùn)練神經(jīng)網(wǎng)絡(luò)
result_test=sim(net, pnewn);%測(cè)試模擬結(jié)果
result_train=sim(net, pn);%訓(xùn)練模擬結(jié)果
[~,I]=max(result_test);%C是得出的result_test中的每一列的最大值虫蝶,I是最大值所在的行數(shù)
[A,B]=max(result_train);%A是得出的result_train中的每一列的最大值,B是最大值所在的行數(shù)
II=I;BB=B;
count_test=0;
count_train=0;
for f=1:40
for g=1:num_test
%計(jì)算在得出的結(jié)果中倦西,被正確識(shí)別出來的測(cè)試集圖片數(shù)目
if(I(1,(f-1)*num_test+g)==f)
count_test=count_test+1;
end
end
for h=1:num_train
%計(jì)算在得出的結(jié)果中能真,被正確識(shí)別出來的訓(xùn)練集圖片數(shù)目
if(B(1,(f-1)*num_train+h)==f)
count_train=count_train+1;
end
end
end
fprintf('統(tǒng)計(jì)結(jié)束:\n正確識(shí)別的測(cè)試集數(shù)目為: %d\n',count_test);
fprintf('正確識(shí)別的訓(xùn)練集數(shù)目為: %d\n',count_train);
%計(jì)算出總識(shí)別率
Total_reg=(count_test+count_train)/400;
disp(['神經(jīng)網(wǎng)絡(luò)人臉識(shí)別率為:',num2str(Total_reg)])
trainJ=cell(1,40);
for k=1:40
trainJ{1,k}= find(B==k);
L(k)=length(trainJ{1,k});
end
Lmax=max(L);
Imtrain=255*ones(40*112, Lmax*92);
imtrain=mat2cell(Imtrain, 112*ones(1,40),92*ones(1,Lmax));
for k=1:40
trainJ{1,k}= find(B==k);
tep=trainJ{1,k};
L=length( trainJ{1,k});
for jk=1:L
tem=reshape(train_picture(tep(jk),:),112,92);
imtrain{k,jk}=tem;
end
end
Imtrain=cell2mat(imtrain);
Lshow=10;%顯示的人數(shù)
showdata= Imtrain(1:Lshow*112, 1:Lmax*92);
imshow( showdata,[]);
title('聚類結(jié)果');
end
%選擇圖片識(shí)別,隨機(jī)選擇圖像
r=randi(40);
rr=randi(10);
d=num2str(rr);
d=['_',d,'.bmp'];
r=int2str(r);
d=[b r d];
select_img=imread(d);
figure
subplot(121); imshow(select_img);title('你選擇的圖片')
M=double(select_img);
num=1;%用最大的奇異值作特征值
x=1;
i=1;
if (featureNumber == 8)
for j=1:4
for k=1:2
%將圖片的灰度矩陣劃分成8塊小矩陣
temp=M((j-1)*28+1:j*28,(k-1)*46+1:k*46);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取一個(gè)的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*2+k)=temp2;
end
end
end
if (featureNumber == 16)
for j=1:4
for k=1:4
%將圖片的灰度矩陣劃分成16塊小矩陣
temp=M((j-1)*28+1:j*28,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
if (featureNumber == 24)
for j=1:6
for k=1:4
%將圖片的灰度矩陣劃分成24塊小矩陣
temp=M((j-1)*18+1:j*18,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
if (featureNumber == 32)
for j=1:8
for k=1:4
%將圖片的灰度矩陣劃分成32塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*23+1:k*23);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
if (featureNumber == 48)
for j=1:8
for k=1:6
%將圖片的灰度矩陣劃分成48塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*15+1:k*15);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*6+k)=temp2;
end
end
end
if (featureNumber == 64)
for j=1:8
for k=1:8
%將圖片的灰度矩陣劃分成64塊小矩陣
temp=M((j-1)*14+1:j*14,(k-1)*11+1:k*11);
%對(duì)每個(gè)小矩陣進(jìn)行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數(shù)作為特征值
temp2=temp1(num,num);
%得到所有圖片的特征矩陣
f((x-1)*10+i,(j-1)*8+k)=temp2;
end
end
end
if (featureNumber == 80)
for j=1:10
for k=1:8
temp=M((j-1)*11+1:j*11,(k-1)*11+1:k*11); %將圖片的灰度矩陣劃分成80塊小矩陣
[u,temp1,v]=svd(temp); %對(duì)每個(gè)小矩陣進(jìn)行SVD變換
temp2=temp1(num,num);%提取最大的SVD系數(shù)作為特征值
f((x-1)*10+i,(j-1)*8+k)=temp2; %得到所有圖片的特征矩陣
end
end
end
f=f';
pnewn1 = mat2gray(f);
result_test=sim(net,pnewn1);
[C,I]=max(result_test);
disp([ '該圖像屬于第',num2str(I),'個(gè)人的人臉圖像']);
subplot(122); imshow(strcat('s',num2str(I),'_', '1.bmp'));title('他/她的第一張圖像')
訓(xùn)練過程
識(shí)別結(jié)果
需要orl人臉庫圖像的評(píng)論一下喔。