Matlab代碼(調用神經網絡工具箱實作人臉識别)
a=input('請輸入你需要提取的特征維數(僅限于8, 16,24, 32,48,64,80):');
for featureNumber =[a]%[8, 16,24, 32, 48, 64, 80]; % 特征維數,僅限于8, 16,24, 32,48,64,80
%% 1.參數配置
save featureNumber featureNumber ;
clear all; close all; warning off; format compact;%rng('default');
load featureNumber ;
disp('##################################################');
disp(['----------------','featureNumber=',num2str(featureNumber ),'時','----------------']);
%% 2.圖檔分塊并計算每塊的最大奇異值,并構成每張圖檔的特征向量
num=1;
%得出圖檔的路徑,并自動讀入每張圖檔
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
%将數字轉換成字元,便于把兩個字元連接配接,組成圖檔的完整路徑
a = int2str(x);
b = ['s'];
d = [b a];
for i=1:10
%得到每張圖檔的檔案名
e = [d dir(i,1:7)];
% 将圖檔轉化成為灰階矩陣
M = double(imread(e));
%如果使用者輸入的是8,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取一個的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*2+k)=temp2;
end
end
end
%如果使用者輸入的是16,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果使用者輸入的是24,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果使用者輸入的是32,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*4+k)=temp2;
end
end
end
%如果使用者輸入的是48,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*6+k)=temp2;
end
end
end
%如果使用者輸入的是64,則執行下段代碼,把資料處理得到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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
temp2=temp1(num,num);
%得到所有圖檔的特征矩陣
feature((x-1)*10+i,(j-1)*8+k)=temp2;
end
end
end
%如果使用者輸入的是80,則執行下段代碼,把資料處理得到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);%對每個小矩陣進行SVD變換
temp2=temp1(num,num);%提取最大的SVD系數作為特征值
feature((x-1)*10+i,(j-1)*8+k)=temp2;%得到所有圖檔的特征矩陣
end
end
end
end
end
tag=0;
for x=1:40
%将數字轉換成字元,便于把兩個字元連接配接,組成圖檔的完整路徑
a = int2str(x);
b = ['s'];
d = [b a];
for i=1:10
tag=tag+1;
%得到每張圖檔的檔案名
e = [d dir(i,1:7)];
%将圖檔轉化成為灰階矩陣
M = double(imread(e));
picture(tag,:)=reshape(M,1,92*112);
end
end
%% 3.屬于預處理(包括劃分訓練集和測試集, 資料歸一化處理等)
num_train=8; %這裡我們設定的每一類資料大小為10, 是以num_train的大小為1~10.
feature=feature'; %進行矩陣倒置,因為該算法要求矩陣的行數比列數少
num_test=10-num_train;
for y=1:40 %構造訓練集,一共有40個人,每人10張圖檔
for n=1:num_train
train_data(:,(y-1)*num_train + n) = feature(:,(y-1)*10 + 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);%構造測試集
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;%構造訓練集目标集
end
end
max_train=max(train_data(:));
min_train=min(train_data(:));
pn = mat2gray(train_data,[min_train ,max_train]);%對訓練集資料進行歸一化處理
pnewn = mat2gray(test_data,[min_train ,max_train]);%對測試集資料進行歸一化處理
%% 4.訓練BP神經網絡
%調用MATLAB神經網絡工具箱,建構BP神經網絡
net = newff(minmax(pn),[110,40],{'tansig','purelin'},'trainrp');
% 函數newff建立一個可訓練的前饋網絡。
% (1) 函數功能:訓練前饋網絡的第一步是建立網絡對象。
% 輸入參數說明:
% 100表示: 輸入隐含層神經元個數
% 40表示: 輸出層的個數(40個人的人臉,即40類)
% 'tansig'表示: 輸入層與隐含層之間的傳遞函數
% 'purelin'表示: 隐含層與輸出層之間的傳遞函數
% 'trainrp'表示: BP網絡訓練函數(有彈回的BP算法,用于消除梯度模值對網絡訓練帶來的影響,提高訓練的速度)
net.trainParam.goal=1e-5;%訓練目标
net.trainParam.epochs=10000;%訓練次數
net.trainParam.lr = 0.005;%學習速率
[net,tr] = train(net,pn,t); % 訓練神經網絡
result_test=sim(net, pnewn);%測試模拟結果
result_train=sim(net, pn);%訓練模拟結果
[~,I]=max(result_test);%C是得出的result_test中的每一列的最大值,I是最大值所在的行數
[A,B]=max(result_train);%A是得出的result_train中的每一列的最大值,B是最大值所在的行數
%%5識别效果
II=I;BB=B;
count_test=0;
count_train=0;
for f=1:40
for g=1:num_test
%計算在得出的結果中,被正确識别出來的測試集圖檔數目
if(I(1,(f-1)*num_test+g)==f)
count_test=count_test+1;
end
end
for h=1:num_train
%計算在得出的結果中,被正确識别出來的訓練集圖檔數目
if(B(1,(f-1)*num_train+h)==f)
count_train=count_train+1;
end
end
end
fprintf('統計結束:\n正确識别的測試集數目為: %d\n',count_test);
fprintf('正确識别的訓練集數目為: %d\n',count_train);
%計算出總識别率
Total_reg=(count_test+count_train)/400;
disp(['神經網絡人臉識别率為:',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;%顯示的人數
showdata= Imtrain(1:Lshow*112, 1:Lmax*92);
imshow( showdata,[]);
title('聚類結果');
end
%%6測試網絡(選擇圖檔識别,随機選擇圖像)
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取一個的SVD系數作為特征值
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
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);
%對每個小矩陣進行SVD變換
[u,temp1,v]=svd(temp);
%提取最大的SVD系數作為特征值
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); %對每個小矩陣進行SVD變換
temp2=temp1(num,num);%提取最大的SVD系數作為特征值
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),'個人的人臉圖像']);
subplot(122); imshow(strcat('s',num2str(I),'_', '1.bmp'));title('他/她的第一張圖像')
訓練過程
識别結果
需要orl人臉庫圖像的評論一下喔……
參考文章
[1]: https://blog.csdn.net/GaotYuan/article/details/79823170