天天看點

基于BP神經網絡人臉識别

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('他/她的第一張圖像')
           

訓練過程

基于BP神經網絡人臉識别

識别結果

基于BP神經網絡人臉識别
基于BP神經網絡人臉識别

需要orl人臉庫圖像的評論一下喔……

參考文章

[1]: https://blog.csdn.net/GaotYuan/article/details/79823170