機器學習的一個主要應用范圍就是對客觀事物的識別,也成為模式識別。模式識別的主要研究目標就是賦予機器可以對生物的信息進行識別和處理。
目前關于模式識別的應用已經得到了比較廣泛的應用,例如 人臉識別,聲音識別,瞳孔識別。
在 前面兩篇文章中(http://blog.csdn.net/eric_sunah/article/details/60139602) http://blog.csdn.net/eric_sunah/article/details/60139824)分別對人臉檢測以及人臉識別的核心算法進行了簡單的介紹,本文主要從代碼層面進行展示。
看代碼前,先來看看人臉識別的大致流程。
人臉識別系統主要包括四個組成部分,分別為:人臉圖像采集及檢測、人臉圖像預處理、人臉圖像特征提取以及匹配與識別。
人臉圖像采集:不同的人臉圖像都能通過攝像鏡頭采集下來,比如靜態圖像、動態圖像、不同的位置、不同表情等方面都可以得到很好的采集。當用戶在采集設備的拍攝范圍內時,采集設備會自動搜索并拍攝用戶的人臉圖像。
人臉檢測:人臉檢測在實際中主要用于人臉識別的預處理,即在圖像中準確標定出人臉的位置和大小。人臉圖像中包含的模式特征十分豐富,如直方圖特征、顏色特征、模板特征、結構特征及Haar特征等。人臉檢測就是把這其中有用的信息挑出來,并利用這些特征實現人臉檢測。 主流的人臉檢測方法基于以上特征采用Adaboost學習算法,Adaboost算法是一種用來分類的方法,它把一些比較弱的分類方法合在一起,組合出新的很強的分類方法。
人臉檢測過程中使用Adaboost算法挑選出一些最能代表人臉的矩形特征(弱分類器),按照加權投票的方式將弱分類器構造為一個強分類器,再將訓練得到的若干強分類器串聯組成一個級聯結構的層疊分類器,有效地提高分類器的檢測速度。
人臉圖像預處理:對于人臉的圖像預處理是基于人臉檢測結果,對圖像進行處理并最終服務于特征提取的過程。系統獲取的原始圖像由于受到各種條件的限制和隨機干擾,往往不能直接使用,必須在圖像處理的早期階段對它進行灰度校正、噪聲過濾等圖像預處理。對于人臉圖像而言,其預處理過程主要包括人臉圖像的光線補償、灰度變換、直方圖均衡化、歸一化、幾何校正、濾波以及銳化等。
人臉圖像特征提?。喝四樧R別系統可使用的特征通常分為視覺特征、像素統計特征、人臉圖像變換系數特征、人臉圖像代數特征等。人臉特征提取就是針對人臉的某些特征進行的。人臉特征提取,也稱人臉表征,它是對人臉進行特征建模的過程。人臉特征提取的方法歸納起來分為兩大類:一種是基于知識的表征方法;另外一種是基于代數特征或統計學習的表征方法。
基于知識的表征方法主要是根據人臉器官的形狀描述以及他們之間的距離特性來獲得有助于人臉分類的特征數據,其特征分量通常包括特征點間的歐氏距離、曲率和角度等。人臉由眼睛、鼻子、嘴、下巴等局部構成,對這些局部和它們之間結構關系的幾何描述,可作為識別人臉的重要特征,這些特征被稱為幾何特征?;谥R的人臉表征主要包括基于幾何特征的方法和模板匹配法。
人臉圖像匹配與識別:提取的人臉圖像的特征數據與數據庫中存儲的特征模板進行搜索匹配,通過設定一個閾值,當相似度超過這一閾值,則把匹配得到的結果輸出。人臉識別就是將待識別的人臉特征與已得到的人臉特征模板進行比較,根據相似程度對人臉的身份信息進行判斷。這一過程又分為兩類:一類是確認,是一對一進行圖像比較的過程,另一類是辨認,是一對多進行圖像匹配對比的過程。
本代碼只含蓋了“人臉識別工作流”章節中,第三部以及第四部。樣本數據取自AT&T人臉數據庫:http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip PCA算法思想請參考:http://blog.csdn.net/eric_sunah/article/details/60139824
# encoding:utf-8import osimport sysimport cv2import numpy as npimport copyimport PIL.Image as Imageimport matplotlib.pyplot as plt"""模擬一個人臉識別系統"""test_face_dir='/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces'test_face_paths=['%s/s10/7.pgm'%(test_face_dir),'%s/s10/6.pgm'%(test_face_dir),'%s/s22/1.pgm'%(test_face_dir),'%s/s18/5.pgm'%(test_face_dir),'%s/s16/3.pgm'%(test_face_dir),'%s/s12/1.pgm'%(test_face_dir)]face_datasource_path=test_face_dir# 定義臉部識別功能類class FaceDetection(object): def __init__(self,train_path): self.eps=1.0e-16 #特征值 self.eig_v=0 #特征向量 self.eig_vect=0 self.mu=0 self.PRojections=[] self.dist_metrics=0 self.path=train_path self.Mat=[] self.X=[] self.Y=[] #加載測試圖片,將圖片數據放到self.X中,將標簽數據放到self.Y中 def load_images(self): print 'start to loading face database images' classlabel=0 for dirname,dirnames,filenames in os.walk(self.path): for subdir in dirnames: subdir_path=os.path.join(dirname,subdir) for subdir_file in os.listdir(subdir_path): subdir_file_path=os.path.join(subdir_path,subdir_file) img=Image.open(subdir_file_path) long_img=img.convert('L') self.X.append(np.asarray(long_img,dtype=np.float64)) self.Y.append(subdir) classlabel+=1 print self.Y #將圖片的數據放入到一個由行向量構成的集成 def gen_row_matrix(self): print 'start converting images to matrix' self.Mat=np.empty((0,self.X[0].size),dtype=self.X[0].dtype) for row in self.X: self.Mat=np.vstack((self.Mat,np.asarray(row).reshape(1,-1))) #圖片庫數據的PCA轉換,并計算出特征向量和均值 def pca(self,k=3): [n,d]=np.shape(self.Mat) if k>n:k=n self.mu=self.Mat.mean(axis=0) # 進行零均值話,減去平均值 self.Mat-=self.mu # 計算協方差矩陣,以及算出特征值與特征向量 if n>d: XTX=np.dot(self.Mat.T,self.Mat) [self.eig_v,self.eig_vect]=np.linglg.eig(XTX) else: XTX=np.dot(self.Mat,self.Mat.T) [self.eig_v,self.eig_vect]=np.linalg.eig(XTX) self.eig_vect=np.dot(self.Mat.T,self.eig_vect) for i in range(n): self.eig_vect[:,i]=self.eig_vect[:,i]/np.linalg.norm(self.eig_vect[:,i]) # 將特征向量按照特征值大小進行從上倒下排列,取前K個 idx=np.argsort(-self.eig_v) self.eig_v=self.eig_v[idx] self.eig_vect=self.eig_vect[:,idx] self.eig_v=self.eig_v[0:k].copy() self.eig_vect=self.eig_vect[:,0:k].copy() #對所有的圖片進行投影操作 def compute(self): print 'start executing pca compute' for xi in self.X: self.projections.append(self.project(xi.reshape(1,-1))) #投影 def project(self,xi): if self.mu is None:return np.dot(xi,self.eig_vect) return np.dot(xi-self.mu,self.eig_vect) #歐式距離 def distEclud(self,vecA,vecB): return np.linalg.norm(vecA-vecB)+self.eps #余旋距離 def comSim(self,vecA,vecB): return (np.dot(vecA,vecB.T)/((np.linalg.norm(vecA)*np.linalg.norm(vecB))+self.eps))[0,0] def train(self): print 'start to trainging face database' self.load_images() self.gen_row_matrix() self.pca() self.compute() # 列出每個分類的平均臉 def subplot(self,title,images): fig=plt.figure() fig.text(.5,.95,title,horizontalalignment='center') for i in xrange(len(images)): ax0=fig.add_subplot(4,4,(i+1)) plt.imshow(np.asarray(images[i]),cmap='gray') #隱藏坐標 plt.xticks([]),plt.yticks([]) plt.show() # 根據路徑生成矩陣對象 def generate_matrix_obj_by_path(self,test_img_path): img=Image.open(test_img_path) long_img=img.convert('L') return np.asarray(long_img,dtype=np.float64) #對目標圖片進行預測 def predict(self,test_img_path): img=self.generate_matrix_obj_by_path(test_img_path) print 'start predicting......' min_dist=np.finfo('float').max min_class=-1 #計算預測圖片的投影 Q=self.project(img.reshape(1,-1)) for i in xrange(len(self.projections)): dist=self.dist_metric(self.projections[i],Q) if dist<min_dist: min_dist=dist min_class=self.Y[i] print 'actualy image is:%s predict result is:%s' %(test_img_path,min_class)def face_detection(): fd=FaceDetection(face_datasource_path) # 指定相似性比較算法 fd.dist_metric=fd.distEclud fd.train() E=[] X=np.mat(np.zeros((10,10304))) #預覽16個人臉庫的數據 for i in xrange(16): # 每種臉包含10張圖片 X=fd.Mat[i*10:(i+1)*10,:].copy() #生成平均臉 X=X.mean(axis=0) imgs=X.reshape(112,92) E.append(imgs) #fd.subplot('AT$T Face Database!',images=E) for test_face_path in test_face_paths: fd.predict(test_face_path)if __name__ =='__main__': face_detection()運行結果:
start to trainging face databasestart to loading face database imagesstart converting images to matrixstart executing pca computestart predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s10/7.pgm predict result is:s10start predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s10/6.pgm predict result is:s10start predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s22/1.pgm predict result is:s22start predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s18/5.pgm predict result is:s18start predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s16/3.pgm predict result is:s16start predicting......actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s12/1.pgm predict result is:s12新聞熱點
疑難解答