日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

模式识别实验之PCA人脸识别

發布時間:2023/12/18 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模式识别实验之PCA人脸识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

模式識別實驗之PCA人臉識別(matlab實現)

  • 一、實驗目的
  • 二、實驗原理
  • 三、實驗步驟
  • 四、matlab編程過程詳解
    • 1、PCA人臉識別的基本流程
    • 2、讀入ROL庫數據
    • 3、PCA特征提取

一、實驗目的

1.通過實驗加深對于PCA人臉識別過程的理解。
2.通過編程進一步提高對圖像、特征向量等概念的理解。

二、實驗原理

PCA方法實現人臉識別,PCA的思想在這里就不詳細論述了。

三、實驗步驟

1.人臉識別圖像庫中包含40個人的頭像圖片,每人10幅。將400張圖像分成兩組,每個人的前五張照片作為訓練圖像,后五張作為測試圖像。讀入圖像,并對圖像數據進行處理。
2.采用PCA方法實現本征臉方法,對特征進行降維。
3.對訓練圖像進行重構,觀察當保留特征維數不同時,重構效果的差異。
4.對測試圖像進行判別。對測試圖像進行預處理,根據本征臉計算重構系數,與每一幅本征臉圖像的重構系數進行比較,根據最小距離進行圖像類別的判別,實現人臉識別。

四、matlab編程過程詳解

1、PCA人臉識別的基本流程


從上圖中可以看出PCA人臉識別分為以下幾個階段:特征提取、構造特征空間、投影計算、分類器決策,我們的程序就是根據流程圖所示編寫。

2、讀入ROL庫數據

%測試數據:40人,每人10張照片。每人取前train_num張照片作為訓練集,后(10-train_num)張照片作為測試集。 clear; clc; train_num=5;%計算特征臉并創建特征空間 imdata=zeros(112*92,40*train_num); for i=1:40 for j=1:train_num addr=strcat('I:/模式識別/實驗四/1107/orl_faces/s',num2str(i),'/',num2str(j),'.pgm');a=imread(addr);%從地址中讀入圖像b=a(1:112*92); %把圖像a矩陣按列順序轉為行向量bimdata(:,train_num*(i-1)+j)=b'; %把b的轉置矩陣存放到imdata矩陣的第ph*(i-1)+j列end end

3、PCA特征提取

3.1得到訓練集的平均臉。
首先我們需要計算這個訓練集的平均臉。

%計算平均臉并顯示 average_face=mean(imdata,2); %按行求平均mean(a,2) 按列mean(a) Average_face=reshape(average_face,112,92);%[112*92,1]的臉灰度數據轉成[112,92] figure; subplot(1,1,1); imshow(Average_face,[]);%imshow(I,[]) 顯示灰度圖像 I,根據 I 中的像素值范圍對顯示進行轉換。 title(strcat('40*5張訓練樣本的平均臉')); clear i j a b addr

運行后得到下圖

這就是該庫中的平均臉,平均臉和樣本庫有很大的關系,不同數據庫得到的平均臉是不一樣的。
3.2計算協方差矩陣并得到特征向量。

%圖像預處理:減去平均均值 immin=zeros(112*92,40*train_num); for i=1:40*train_num immin(:,i) = imdata(:,i)-average_face; end clear i %計算協方差矩陣 %W=immin*immin';%dxn*nxd =dxd,由N*N降為d*d W=immin'*immin; %n*d x d*n= n*n 較小 %計算特征向量與特征值(向量) [V,D]=eig(W);

該庫中的每個特征向量是一個10304x1的向量,即仍然是一個112x92的圖像,這些特征向量的圖像任然具有一些人臉的特點,因此被稱作“本征臉”。
下面給出了所得的部分特征臉:


我們可以發現前面三張特征臉看上去要比后面三張特征臉“清楚”得多,也就是說前三張特征臉所包含的“信息”要比后三張所包含的“信息”多。其實這是由于這些特征向量對應的特征值的大小不同造成的,特征值越大,則人臉越“清晰”。

3.3選取部分特征值
從3.2節中我們知道有些特征臉所攜帶的“信息”十分少,那么我們可以將所得到的所有特征臉按照特征值的大小排序,選取累計貢獻值大于85%的前neednum個特征臉,這樣一來在盡可能小的影響模型精度的情況下對特征空間降維。

%對特征向量進行排序 [D_sort,index] = sort(diag(D),'descend'); SumAllFaceEigenValue=sum(D_sort); NowFaceEigenValue=0;%選取累計貢獻大于90%的前neednum個特征臉 for i=1:size(D_sort,1) NowFaceEigenValue=NowFaceEigenValue+D_sort(i); neednum=i; if(NowFaceEigenValue>SumAllFaceEigenValue*0.85)%累計貢獻率達到85%以上即可break; end end V_sort = V(:,index); VT=immin*V_sort; %dxn*nxk=d*k for i=1:40*train_numVT(:,i)=VT(:,i)/norm(VT(:,i));%歸一化處理 end newVT=VT(:,1:neednum);%取前neednum個特征值

(可選)我們也可以將排序后的特征臉輸出保存

%顯示前32個(32是為了顯示方便選取的)特征臉,并保存所有的特征臉(200個)到image中(已按從大到小排序)figure;mkdir image % 如果文件夾已存在,會有警告,但不影響運行 for i=1:200v=VT(:,i);%向量矩陣化out=reshape(v,112,92); %(112*92)x1的列向量轉成112x92的矩陣if i<=32subplot(4,8,i);imshow(out,[]);endimwrite(mat2gray(out),strcat( 'image/test',num2str(i),'.png'));title(strcat('Face',num2str(i))); end clear i v out


(中間部分圖片已省略…)

我們可以看到,所有的特征臉已經按照“清晰度”(特征值)從大到小排序了。但是其實我們只需要選取累計貢獻大于85%的前neednum個特征臉,于是我們把這些需要的特征臉保存到newVT中:

newVT=VT(:,1:neednum);%取前neednum個特征值

這neednum個特征向量就構成了我們需要的特征空間。
至此我們完成了計算協方差矩陣并得到特征向量,
3.4訓練樣本集在特征空間的投影及人臉圖像的重建

face_train_projection=zeros(neednum,40*train_num); for i=1:40*train_num%映射訓練集圖像Coefficient=newVT'*immin(:,i); %k*d x d*1=k*1;face_train_projection(:,i)=Coefficient; end clear i Coefficient

根據人臉在特征空間中投影后的系數我們可以將人臉重建。根據PCA的相關知識我們可以知道當neednum等于總數(200)時,重建后的圖像是的原圖無差圖像。

figure;er=zeros(20,1);%生成重建圖%建立存放目錄,只需執行一次%mkdir('I:\模式識別\實驗四\Rebuild_face');%for i=1:40%mkdir(strcat('I:\模式識別\實驗四\Rebuild_face\s',num2str(i)));%endfor inum=1:200people=inum; for step=10:10:200x=average_face;for ii = 1:stepx=x+VT(:,ii)'*(imdata(:,people)-average_face)* VT(:,ii);ender(step/10)=sqrt(sum(sum((x-imdata(:,people)).^2)));newX=reshape(x,112,92);subplot(4,5,step/10);set(gcf,'outerposition',get(0,'screensize'));imshow(newX,[]);title(strcat('選取',num2str(step),'個特征臉的重建圖像')); endsaveas(gcf,['Rebuild_face/s',num2str(ceil(inum/5)),'/','重建圖',num2str(mod(inum,5)),'.tiff']);end

我們也可以計算這過程中的誤差:

%繪制誤差曲線圖people=3; for step=10:10:200x=average_face;for ii = 1:stepx=x+VT(:,ii)'*(imdata(:,people)-average_face)* VT(:,ii);ender(step/10)=sqrt(sum(sum((x-imdata(:,people)).^2)));newX=reshape(x,112,92);subplot(4,5,step/10);set(gcf,'outerposition',get(0,'screensize'));imshow(newX,[]);title(strcat('選取',num2str(step),'個特征臉的重建圖像')); endER=(er-min(er))/(max(er)-min(ER));figure; plot(ER,'k'); set(gca, 'XTick', [0 :20]); set(gca,'XTickLabel',[0 :10:200]) ; xlabel('選取的特征臉數量'); ylabel('誤差');

可以得到下圖:

我們可以看到隨著neednum的值不斷增加,誤差在逐漸減小。除了按照貢獻度來選擇neednum的大小,我們也可以根據具體誤差的要求來選擇合適的neednum。

3.5利用測試集測試,并得到錯誤率。
我們先讀取測試集,并將測試集投影到特征空間中:

%讀入樣本數據 test=zeros(112*92,40*(10-train_num)); for i=1:40 for j=(train_num+1):10 %610,后五張作為測試樣本addr=strcat('I:/模式識別/實驗四/1107/orl_faces/s',num2str(i),'/',num2str(j),'.pgm');a=imread(addr);b=a(1:112*92); test(:,(10-train_num)*(i-1)+(j-train_num))=b';end end %減去平均臉 testmin=zeros(112*92,40*(10-train_num)); for i=1:40*(10-train_num) testmin(:,i) = test(:,i)-average_face; end clear i j a b addr testface_test_projection=zeros(neednum,40*(10-train_num)); for i=1:40*(10-train_num)%映射測試集圖像Coefficient=newVT'*testmin(:,i);face_test_projection(:,i)=Coefficient; end clear i Coefficient

這樣我們得到了 face_test_projection和face_train_projection這兩個投影向量,對于face_test_projection中的每一列(每一張圖片在投影空間是一個列向量)而言,它總能在face_train_projection中找到一個與它距離最小的一個列向量,那么我們就可以設計一個最小距離分類器來實現分類(也可以利用Fisher線性分類器,可能效果會更好一點),從而實現人類識別:

%識別,并計算錯誤率 error=0;%判錯數 for num=1:40*(10-train_num) class=minindex(num,face_train_projection,face_test_projection); display(strcat('測試集中的第',num2str(num),'張圖片屬于類別:S',num2str(class)));if class~=ceil(num/5)error=error+1;end end display(strcat('測試中判錯數為:',num2str(error),'張,正確數為:',num2str(length(face_test_projection)-error),'張,錯誤率為:',num2str(100*error/length(face_test_projection)),'%'));

minindex函數:

function class=minindex(class_num,face_train_projection,face_test_projection)distance=zeros(length(face_train_projection),1); for p=1:length(face_train_projection)distance(p)=normest(face_test_projection(:,class_num)-face_train_projection(:,p)); end [num,index ]=min(distance); class=ceil(index/5);

下面是運行結果:
》》 recognition
測試集中的第1張圖片屬于類別:S1
測試集中的第2張圖片屬于類別:S1
測試集中的第3張圖片屬于類別:S1
測試集中的第4張圖片屬于類別:S1
*
*
*
測試集中的第197張圖片屬于類別:S40
測試集中的第198張圖片屬于類別:S40
測試集中的第199張圖片屬于類別:S40
測試集中的第200張圖片屬于類別:S40
測試中判錯數為:23張,正確數為:177張,錯誤率為:11.5%
至此,我們實現了利用PCA對ORL人臉庫進行識別。

總結

以上是生活随笔為你收集整理的模式识别实验之PCA人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。