Eigenface與PCA人臉識別算法實驗

簡單的特徵臉識別實驗


實現特徵臉的過程其實就是主成分分析(Principal Component Analysis,PCA)的一個過程。關於PCA的原理問題,它是一種數學降維的方法。是爲了簡化問題。在二維的座標空間內,找到一個單位向量U,使得全部數據在U上的投影之和最大。這樣就能把數據分的儘量的開。而後把訓練樣本投影到這個向量U上,把測試圖片也投影上去,計算這個投影與各個樣本人臉投影的歐式距離,得出最小的歐式距離的的那個樣本編號,就是最大機率的人臉。算法

Eigenface算法


特徵臉方法(Eigenface)是一個經典算法的人臉識別算法。特徵臉方法是從PCA導出的一種人臉識別和描述技術。就是將包含人臉的圖像區域看做是一種隨機向量,所以能夠採用K-L變換得到其正交K-L基底。對應其中較大特徵值的基底具備與人臉類似的形狀,所以又稱爲特徵臉。利用這些基底的線性組合能夠描述、表達和逼近人臉圖像,所以能夠進行人臉識別與合成。識別過程就是將人臉圖像映射到由特徵臉構成的子空間上,比較其與己知人臉在特徵空間中的位置,具體步驟以下:數據庫

(1) 初始化,得到人臉圖像的訓練集並計算特徵臉,定義爲人臉空間,存儲在模板庫中,以便系統進行識別;這裏使用Yalefaces數據庫。這裏面有15我的,每一個人的文件夾中取一張正常狀態的圖像,size爲(98,116),並用flatten()把該圖像轉換成一維向量。15張這樣的圖組成一個(8100,15)的矩陣;app

(2) 對每一行求均值,獲得一個(11368,1)的向量avgImg,這個圖像就是平均臉;測試

(3) 將圖像矩陣與平均臉相減,獲得誤差值diffTrain,用誤差值計算協方差,協方差矩陣C= XXTspa

(4) 這裏須要作一個變換,由於C算出來爲都會很是大,能夠改成計算C’,設C’ = XTX,設這裏算出的特徵向量爲E’,XE’= E,這裏E就是本來該C獲得的特徵向量。而後把E歸一化。code

人臉識別


這裏獲得了15個特徵臉以後,考慮選擇出主成分。這裏取特徵向量超過特徵向量均值的80%的幾個特徵向量,假設是K個,這K個特徵向量組成的矩陣設爲w。將誤差矩陣轉置乘以w,獲得協方差矩陣的特徵向量。orm

(1) 輸入新的人臉圖像,轉換成一維向量,將其映射到特徵臉空間,獲得一組關於該人臉的特徵數據;blog

(2) 經過檢查圖像與人臉空間的距離判斷它是不是人臉;圖片

(3) 若爲人臉,根據權值模式判斷它是否爲數據庫中的某我的,並作出具體的操做。ip

代碼以下:

  1 import numpy as np
  2 
  3 from numpy import *
  4 
  5 from numpy import linalg as la
  6 
  7 from PIL import Image
  8 
  9 import glob
 10 
 11 from matplotlib import pyplot as plt
 12 
 13 def loadImageSet(add):
 14 
 15  filenames = glob.glob('face/pgm/*.pgm')
 16 
 17  filenames.sort()
 18 
 19  img = [Image.open(fn).convert('L').resize((98, 116)) for fn in filenames]
 20 
 21  FaceMat = np.asarray([np.array(im).flatten() for im in img])
 22 
 23  return FaceMat
 24 
 25 def ReconginitionVector(selecthr = 0.8):
 26 
 27  # step1: load the face image data ,get the matrix consists of all image
 28 
 29  FaceMat = loadImageSet('face/yalefaces/')
 30 
 31  print('-----------FaceMat.shape--------')
 32 
 33  print(FaceMat.shape)
 34 
 35  # step2: average the FaceMat
 36 
 37  avgImg = mean(FaceMat,0)
 38 
 39  # step3: calculate the difference of avgimg and all image data(FaceMat)
 40 
 41  diffTrain = FaceMat-avgImg
 42 
 43  covMat =np.asmatrix(diffTrain) * np.asmatrix(diffTrain.T)
 44 
 45  eigvals,eigVects = linalg.eig(covMat) #la.linalg.eig(np.mat(covMat))
 46 
 47  #step4: calculate eigenvector of covariance matrix (because covariance matrix will cause memory error)
 48 
 49  eigSortIndex = argsort(-eigvals)
 50 
 51  for i in range(shape(FaceMat)[1]):
 52 
 53  if (eigvals[eigSortIndex[:i]]/eigvals.sum()).sum() >= selecthr:
 54 
 55  eigSortIndex = eigSortIndex[:i]
 56 
 57  break
 58 
 59  covVects = diffTrain.T * eigVects[:,eigSortIndex] # covVects is the eigenvector of covariance matrix
 60 
 61  # avgImg 是均值圖像,covVects是協方差矩陣的特徵向量,diffTrain是誤差矩陣
 62 
 63  return avgImg,covVects,diffTrain
 64 
 65 def judgeFace(judgeImg,FaceVector,avgImg,diffTrain):
 66 
 67  diff = judgeImg - avgImg
 68 
 69  weiVec = FaceVector.T* diff.T
 70 
 71  res = 0
 72 
 73  resVal = inf
 74 
 75 #==============================================================================
 76 
 77 # plt.imshow(avgImg.reshape(98,116))
 78 
 79 # plt.show()
 80 
 81 #==============================================================================
 82 
 83  for i in range(15):
 84 
 85  TrainVec = (diffTrain[i]*FaceVector).T
 86 
 87  if (array(weiVec-TrainVec)**2).sum() < resVal:
 88 
 89  res = i
 90 
 91  resVal = (array(weiVec-TrainVec)**2).sum()
 92 
 93  return res+1
 94 
 95 if __name__ == '__main__':
 96 
 97  avgImg,FaceVector,diffTrain = ReconginitionVector(selecthr = 0.8)
 98 
 99  nameList = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15']
100 
101  characteristic = ['centerlight','glasses','happy','leftlight','noglasses','rightlight','sad','sleepy','surprised','wink']
102 
103  for c in characteristic:
104 
105  count = 0
106 
107  for i in range(len(nameList)):
108 
109  # 這裏的loadname就是咱們要識別的未知人臉圖,咱們經過15張未知人臉找出的對應訓練人臉進行對比來求出正確率
110 
111  loadname = 'face/yalefaces/subject'+nameList[i]+'.'+c+'.pgm'
112 
113  judgeImg = Image.open(loadname).convert('L').resize((98, 116))
114 
115  #print(loadname)
116 
117  if judgeFace(mat(judgeImg).flatten(),FaceVector,avgImg,diffTrain) == int(nameList[i]):
118 
119  count += 1
120 
121 print('accuracy of %s is %f'%(c, float(count)/len(nameList))) # 求出正確率

運行結果:

 1 accuracy of centerlight is 0.400000
 2 
 3 accuracy of glasses is 0.533333
 4 
 5 accuracy of happy is 0.866667
 6 
 7 accuracy of leftlight is 0.133333
 8 
 9 accuracy of noglasses is 0.800000
10 
11 accuracy of rightlight is 0.133333
12 
13 accuracy of sad is 0.800000
14 
15 accuracy of sleepy is 0.800000
16 
17 accuracy of surprised is 0.666667
18 
19 accuracy of wink is 0.600000
相關文章
相關標籤/搜索