matlab自带的人脸分类器,基于MATLAB,运用PCA+SVM的特征脸方法人脸识别
概述:
此文章將要描述一種基于MATLAB平臺,運用PCA主成分分析方法對圖片數據進行降維,運用SVM支持向量機分類器對降維后的圖片數據進行分類處理,從而達到人臉識別的目的。
首先要感謝以下幾篇文章的作者(后面引用會標識文章標號)
2.
PCA (主成分分析)詳解 (寫給初學者) 結合matlab(F),E篇列出了具體的數據供大家檢驗,大家可以根據數據來驗證數學過程,簡單易懂。F篇與前篇有點相似,對初學者很有幫助。
4.淺談協方差矩陣(G)此篇文章對于大家了解協方差矩陣以及matlab實現很有作用。
準備:
1.編程平臺:MATLAB。
首先你得保證你的機器上安裝有matlab,建議較高的版本。
2.libsvm工具箱。
本人在對第一篇文章中代碼關于SVM分類的部分沒有運行成功,所以運用了libsvm工具箱對樣本訓練,測試,并沒有運用第一篇文章的代碼,如果你能成功可忽略,但建議安裝此工具箱,其對SVM分類有很大幫助。如果你一樣沒有成功,這里推薦一個鏈接,有關于libsvm工具箱的安裝配置的視頻。
3.數據:ORL人臉庫。
這個數據為已經預處理的數據,格式為pgm,屬于Linux格式,windows環境下無法直接打開,可以在matlab中打開,打開方式imshow(imread('圖片路徑'));數據是400張人臉圖片,屬于40個人,每個人10張,每張大小112*92像素,數據下載地址在第一篇文章中有,這里也給個鏈接,第四段兩個鏈接都可下載。
4.主成分分析法PCA。
主成分分析法是一種降維的方法,上面給出了幾個有用的鏈接,本文只給出代碼,以及代碼說明,關于原理,大家盡可參照上面幾個鏈接,寫得非常詳細也非常通俗。
5.SVM支持向量機分類器。
SVM支持向量機是一個二類分類器,但是本次人臉識別不僅只是分出兩類,而是需要分出40個類別。本人以前有過一點機器學習基礎,所以在支持向量機原理的理解上沒有多大問題,如果讀者沒有SVM基礎,可參考SVM入門(H),以及寫的非常給力的帖子,SVM三層境界(I)。
注:也許很多初學者看到這么多的資料,鏈接都已經暈了,失去了學習的動力。先別灰心,稍后我會把代碼以及代碼運行的結果和過程展示給大家,當大家看到這些圖像的變換的美妙,就會有學習的興趣。
編程實現:
以下將要展示的是幾個.m文件的代碼,.m文件即是能在matlab上面打開運行的代碼文件,可以在其中定義函數,如果matlab的當前路徑指定在含有這些.m文件的文件夾中,運行時就可以調用這些文件中定義的函數。
首先展示第一個.m文件,便是圖片數據讀取函數ReadFace.m
function?[f_matrix,realclass]=ReadFace(n_persons,flag)
%ORL人臉庫。pgm格式的圖片。40人,每人10幅圖,圖像大小為112*92像素。
%每個人有10幅照片,前5幅當作訓練集,后5幅當作測試集
%
%輸入變量flag:
%???flag是一個標識變量
%???當flag為0時,表示輸入為訓練集,flag為1時,表示輸入為測試集
%
%輸入變量n_persons:
%???n_persons標志著你想要識別的人臉個數
%
%輸出變量realclass:
%???realclass是一個n_person*5行,1列的列向量。
%???realclass即是數據的標簽,無論訓練集測試集都進行了標簽處理
%
%輸出變量f_matrix:
%???f_matrix是一個n_person*5行,112*92列的矩陣
%???每一行便是每一張圖片的灰度數據
%???將每一張圖片列向量排成一個列向量后轉置得到放入f_matrix各行當中
imgrow=112;imgcol=92;
global?imgrow;???%載入圖片行數
global?imgcol;????%載入圖片列數
realclass=zeros(n_persons*5,1);
f_matrix=zeros(n_persons*5,imgrow*imgcol);
for?i=1:n_persons
%路徑設置
%函數num2str(i)說明:將數字轉化為字符
facepath=strcat('F:\MATLAB人臉識別\Face\facedata\s',num2str(i),'\');??%路徑因不同情況而定
cachepath=facepath;
for?j=1:5
facepath=cachepath;
if?flag==0
%函數strcat(a,b,...)說明:將輸入字符a,b...連接成單個字符
facepath=strcat(facepath,num2str(j));
else
facepath=strcat(facepath,num2str(j+5));
end
realclass((i-1)*5+j)=i;
facepath=strcat(facepath,'.pgm');
%函數imread說明:讀取輸入路徑的圖片,將每個像素灰度值保存在輸出的矩陣中
img=imread(facepath);
f_matrix((i-1)*5+j,:)=img(:)';
end
end
end
代碼當中有著詳細的注釋,代碼與第一篇文章中提供的代碼大同小異,根據本人情況修改了一點路徑的代碼,以及增加了對訓練集標簽的標識,且增加了注釋?,F在對代碼進行一些說明。
代碼第一行有對函數的申明,function []=ReadFace(),中括號為函數的輸出,小括號為函數的輸入,函數名與文件名一致,一個.m文件當中可以有多個函數申明,但當外面的函數想要調用這個文件中的函數時,只能調用與文件名一致的函數。所以這個文件叫ReadFace.m。
何為訓練集以及測試集?
在機器學習方法當中,分為監督學習,非監督學習,強化學習。而SVM支持向量機是一種監督學習的算法。所謂監督學習,就是給予機器一套題目并附上標準答案,讓它去做題,自己總結了一套做題的方法(這些方法就是建立的模型),它在根據已經學習好的方法來做一套新的題目,把題目做對,盡可能打高分。
訓練集就是給予機器的一套題目及標準答案,測試集就是給它的一套新題。而訓練集有標簽和數據之分,標簽就是標準答案,標簽有著1和0,就表示這些訓練集中有兩類,像我們的人臉數據有40種人臉,我們就用1到40來表示。數據就是有著多維的表征一個事物的數據,就是給機器的第一套題目。測試集也有數據,就是后面給機器測試的題目,如果測試集原本含有標簽,這些標簽就可以作為標準給機器前面訓練總結的方法(模型)打分,查看準確率。
在這個人臉庫中,每個人有10張圖,我們將前5張作為訓練集,就有200張圖。用一個矩陣來表示這200張圖,就形成了一個200*10304的矩陣。后5張圖用來當測試集,可以看代碼中的說明。
當flag為0時,找出訓練集的標簽realclass(200*1的矩陣)與數據f_matrix(200*10304的矩陣).
當flag為1時,就是找出測試集來測試分類效果,得出準確率。
SVM訓練的目的就是利用訓練集找到這么一個分類函數(模型),再在測試集中檢測。關于SVM的具體原理查看上面的H和I篇。
--------------------------------分割線---------------------------------------
第二個.m文件的文件名為fastPCA.m,用于將樣本進行降維處理,參考上面主成分分析PCA文章D,E,F篇,上面有通俗且具體的闡述。
function?[?pcaA,V]?=?fastPCA(?A,k,mA)
%快速PCA,主成份分析
%輸入:A-樣本矩陣,每行是一個樣本,列是樣本的維數
%????????????k-降至k維
%???????????mA-圖像矩陣f_matrix每一列的均值排成一個行向量,即mean(f_matrix)
%輸出:pacA-降維后,訓練樣本在低維空間中的系數坐標表示
%????????????V-主成分分量,即低維空間當中的基
%
m=size(A,1);??%m為讀取圖片的張數
Z=(A-repmat(mA,m,1));??%中心化樣本矩陣
%一般用中心化的矩陣代替原矩陣。為什么?因為將數據集的均值歸零(預處理),也就是只取數據的偏差部分
T=Z*Z';
[V1,D]=eigs(T,k);%計算T的最大的k個特征值和特征向量
V=Z'*V1;?????????%協方差矩陣的特征向量
%這一點是關鍵步驟,很可能很多初學者無法理解:
%按理來講,協方差矩陣的計算公式為(假設上面中心化的Z已經求出):
%V?=?(Z'*Z)./(size(Z,1)-1)(先不管單位化,V=Z'*Z)(這里是一行為一個樣本,一列為一個維數的情況)
%協方差矩陣是N*N的方陣,維數N應該與原圖片f_matrix(200*10304)維數相等
%f_matrix中行數200為圖片個數,列數10304為維數
%那為什么這里是T=Z*Z',再求T的K個最大特征值和特征向量V1,再用V=Z'*V1來求協方差矩陣特征向量呢?
%因為我們如果求V=Z'*Z這個V就是一個10304*10304的矩陣,MATLAB奔潰了,太復雜
%我們可以這樣看P^-1*(Z*Z')*P=S等價于P^-1*(Z')^-1*Z'*Z*Z'*P=S等價于(Z'*P)^-1*(Z'*Z)*(Z'*P)=S
%注:P^-1是P的逆矩陣,(Z')^-1為Z'的逆矩陣,類推,建議大家寫在紙上
%最后一個式子可以看出Z'*Z的特征向量矩陣為Z'*P,而Z*Z'的特征向量矩陣為P,即為程序中的V1
%這是一種簡便方法,為的就是避免像V=Z'*Z這種維數太高的計算。
%可查看C篇文章步驟4
for?i=1:k???????%特征向量單位化
l=norm(V(:,i));
V(:,i)=V(:,i)/l;
end
%單位化后的V才能是真正的低維空間的基,需要滿足正交化單位化兩個條件
%具體原因參考D篇文章
pcaA=Z*V;???????%線性變換,降至k維??,將中心化的矩陣投影到低維空間的基中,V就是低維空間的基
%pcaA為低維空間的坐標表示,即一個圖像的判斷依據
end
代碼與第一篇文章代碼沒有不同,只是多加了注釋,便于大家理解。
下面貼出原圖,均值臉以及兩者的差值圖:
-------------------------------------------------分割線---------------------------------------------------------
第三個文件為scaling.m文件,其中的代碼與原作者代碼無二。略加注釋。function?[?scaledface]?=?scaling(?faceMat,lowvec,upvec?)
%特征數據規范化
%即是將同一個樣本中的不同維度歸一化
%因為因為對于不同的屬性,如果不歸一化是不具有比較性的,兩者不在一個量級上
%輸入——faceMat需要進行規范化的圖像數據,
%????????????????lowvec原來圖像數據中的最小值
%????????????????upvec原來圖像數據中的最大值
upnew=1;
lownew=-1;
[m,n]=size(faceMat);
scaledface=zeros(m,n);
for?i=1:m
scaledface(i,:)=lownew+(faceMat(i,:)-lowvec)./(upvec-lowvec)*(upnew-lownew);
%將圖像數據中一個樣本的不同維度的值,最小值和最大值規范到-1和1,其他值按比例規范到(-1,1)
end
end
-----------------------------------------------------分割線-----------------------------------------------------
第四個文件visualize.m中為顯示特征臉的代碼,比較簡單,并附上顯示結果。function?visualize(?B?)
%顯示特征臉(變換空間中的基向量,即單位特征向量)
%輸入:B——每列是個主成分分量,顯示的就是低維中每個基組成的圖像
%?????k——主成分的維數
global?imgrow;
global?imgcol;
figure
img=zeros(imgrow,imgcol);
for?i=1:20
img(:)=B(:,i);
subplot(4,5,i);
imshow(img,[])
end
end
因為降至20維,所以其在低維中的基便是這20張特征臉,其他所有的經過了降維的臉都可以由這20張特征臉線性表示,即我們要進行臉部識別時,把選擇要識別的臉進行降維處理后,再右乘這些基(特征臉)所構成的矩陣,就能得到這些臉在低維中的線性表示。這些表示就是識別的依據。
特征臉截圖:
-------------------------------------------------分割線---------------------------------------------------------
第五個文件recognition.m中的代碼,在A篇文章當中沒有,是我自己編寫的臉部識別的小程序,比較簡單,沒有像A篇文章中一樣做GUI界面。function?recognition(mA,V,model)
%函數作用:人臉識別模塊,利用已經建好的模型,重新找一個樣本進行識別
%輸入:
%???????????mA-均值
%???????????V-協方差矩陣特征向量
%???????????model-通過SVM對訓練集訓練得出的已經建立好的模型
%%
global?imgrow;
global?imgcol;
%%
%彈出輸入框,選擇要識別的圖片
select_person_num=str2double(cell2mat(inputdlg('請輸入想要識別的人的編號(總共40個人):')));%總共40個人
select_img_num=str2double(cell2mat(inputdlg('請輸入此人圖片的編號(總共10張):')));%總共10張圖
%%
%對圖片信息進行處理,化為1*10304的行向量
disp('讀取選擇的圖片...')
select_facepath=strcat('F:\MATLAB人臉識別\Face\facedata\s',num2str(select_person_num),'\',num2str(select_img_num),'.pgm');
select_img=imread(select_facepath);
select_matrix=zeros(1,imgrow*imgcol);
select_matrix(1,:)=select_img(:)';
select_matrix=(select_matrix-mA)*V;%PCA降維后的低維表示
%%
%圖形歸一化
disp('規范化選擇的圖片...')
select_matrix?=?scaling(?select_matrix,min(select_matrix),max(select_matrix));
%%
%測試選擇的圖片,accuracy只有兩個值,100%表示匹配正確,0%表示匹配錯誤
disp('測試選擇的圖片...')
[select_predict_label,accuracy,decision_values]=svmpredict(select_person_num,select_matrix,model);
%%
%顯示原有圖片和匹配圖片進行比較
disp('顯示選擇的圖片...')
figure(2);
subplot(1,2,1);imshow(select_img);title('你選擇的圖片');
subplot(1,2,2);
imshow(imread(strcat('F:\MATLAB人臉識別\Face\facedata\s',num2str(select_predict_label),'\',num2str(1),'.pgm')));
title('匹配的圖片');
程序運行到此會彈出輸入框,讓用戶選擇想要識別的圖片,當Accuracy=100%表示識別正確,如果Accuracy=0%表示識別錯誤。
? ? ? ? ??
? ? ? ? ??
輸入編碼后選擇的圖片,以及匹配到的圖片對比。
-------------------------------------------------分割線---------------------------------------------------------
第六個文件face.m中的代碼為主程序。讀者想要看到整個效果,只需要將此文件中的程序全部選中按F9即可運行。
注:我的SVM分類器是用libsvm工具箱當中的函數實現的兩個關鍵函數便是svmtrain和svmpredict,核函數選用線性核函數。
以上暫時是初稿,肯定還有很多需要修改的地方,如果讀者有什么疑問或是看到什么錯誤,希望能留言,我會加以請教。大家相互學習,相互進步。
轉自:http://blog.csdn.net/yb536/article/details/40586695
總結
以上是生活随笔為你收集整理的matlab自带的人脸分类器,基于MATLAB,运用PCA+SVM的特征脸方法人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android tag 快捷_Andro
- 下一篇: dijkstra算法matlab程序_D