人臉識別經典算法實現

2021-02-18 單片機與嵌入式

最近研究了一下人臉識別,發現裡面很有門道啊,我是初入,還不是很理解,只能到時看看論壇,到處學習啊。感謝各位先人的帖子和代碼。本帖部分原創,部分借用,如有雷同,純屬巧合!!!
首先需要2個第三方的庫
opencv-python、numpy
安裝完成後,可以編程了,還是先說明一下需要的算法:

特徵子臉技術的基本思想是:從統計的觀點,尋找人臉圖像分布的基本元素,即人臉圖像樣本集協方差矩陣的特徵向量,以此近似地表徵人臉圖像。這些特徵向量稱為特徵臉(Eigenface)。

實際上,特徵臉反映了隱含在人臉樣本集合內部的信息和人臉的結構關係。將眼睛、面頰、下頜的樣本集協方差矩陣的特徵向量稱為特徵眼、特徵頜和特徵唇,統稱特徵子臉。特徵子臉在相應的圖像空間中生成子空間,稱為子臉空間。計算出測試圖像窗口在子臉空間的投影距離,若窗口圖像滿足閾值比較條件,則判斷其為人臉。 
    基於特徵分析的方法,也就是將人臉基準點的相對比率和其它描述人臉臉部特徵的形狀參數或類別參數等一起構成識別特徵向量,這種基於整體臉的識別不僅保留了人臉部件之間的拓撲關係,而且也保留了各部件本身的信息,而基於部件的識別則是通過提取出局部輪廓信息及灰度信息來設計具體識別算法。現在Eigenface(PCA)算法已經與經典的模板匹配算法一起成為測試人臉識別系統性能的基準算法;而自1991年特徵臉技術誕生以來,研究者對其進行了各種各樣的實驗和理論分析,FERET'96測試結果也表明,改進的特徵臉算法是主流的人臉識別技術,也是具有最好性能的識別方法之一。
    該方法是先確定眼虹膜、鼻翼、嘴角等面像五官輪廓的大小、位置、距離等屬性,然後再計算出它們的幾何特徵量,而這些特徵量形成一描述該面像的特徵向量。其技術的核心實際為「局部人體特徵分析」和「圖形/神經識別算法。」這種算法是利用人體面部各器官及特徵部位的方法。如對應幾何關係多數據形成識別參數與資料庫中所有的原始參數進行比較、判斷與確認。Turk和Pentland提出特徵臉的方法,它根據一組人臉訓練圖像構造主元子空間,由於主元具有臉的形狀,也稱為特徵臉  ,識別時將測試  圖像投影到主元子空間上,得到一組投影係數,和各個已知人的人臉圖像比較進行識別。Pentland等報告了相當好的結果,在 200個人的 3000幅圖像中得到 95%的正確識別率,在FERET資料庫上對 150幅正面人臉象只有一個誤識別。但系統在進行特徵臉方法之前需要作大量預處理工作如歸一化等。
    在傳統特徵臉的基礎上,研究者注意到特徵值大的特徵向量 (即特徵臉 )並不一定是分類性能好的方向,據此發展了多種特徵 (子空間 )選擇方法,如Peng的雙子空間方法、Weng的線性歧義分析方法、Belhumeur的FisheRFace方法等。事實上,特徵臉方法是一種顯式主元分析人臉建模,一些線性自聯想、線性壓縮型BP網則為隱式的主元分析方法,它們都是把人臉表示為一些向量的加權和,這些向量是訓練集叉積陣的主特徵向量,Valentin對此作了詳細討論。總之,特徵臉方法是一種簡單、快速、實用的基於變換係數特徵的算法,但由於它在本質上依賴於訓練集和測試集圖像的灰度相關性,而且要求測試圖像與訓練集比較像,所以它有著很大的局限性。

基於KL 變換的特徵人臉識別方法
基本原理:
    KL變換是圖象壓縮中的一種最優正交變換,人們將它用於統計特徵提取,從而形成了子空間法模式識別的基礎,若將KL變換用於人臉識別,則需假設人臉處於低維線性空間,且不同人臉具有可分性,由於高維圖象空間KL變換後可得到一組新的正交基,因此可通過保留部分正交基,以生成低維人臉空間,而低維空間的基則是通過分析人臉訓練樣本集的統計特性來獲得,KL變換的生成矩陣可以是訓練樣本集的總體散布矩陣,也可以是訓練樣本集的類間散布矩陣,即可採用同一人的數張圖象的平均來進行訓練,這樣可在一定程度上消除光線等的幹擾,且計算量也得到減少,而識別率不會下降。


下面開始編程,過程中發現pcv好複雜啊,增加了些列印,方便調試用。

#encoding=utf-8  

import numpy as np  

import cv2  

import os  

  

class EigenFace(object):  

    def __init__(self,threshold,dimNum,dsize):  

        self.threshold = threshold # 閾值暫未使用  

        self.dimNum = dimNum  

        self.dsize = dsize  

  

    def loadImg(self,fileName,dsize):  

        ''''' 

        載入圖像,灰度化處理,統一尺寸,直方圖均衡化 

        :param fileName: 圖像文件名 

        :param dsize: 統一尺寸大小。元組形式 

        :return: 圖像矩陣 

        '''  

        img = cv2.imread(fileName)  

        retImg = cv2.resize(img,dsize)  

        retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY)  

        retImg = cv2.equalizeHist(retImg)  

        # cv2.imshow('img',retImg)  

        # cv2.waitKey()  

        return retImg  

  

  

    def createImgMat(self,dirName):  

        ''''' 

        生成圖像樣本矩陣,組織形式為行為屬性,列為樣本 

        :param dirName: 包含訓練數據集的圖像文件夾路徑 

        :return: 樣本矩陣,標籤矩陣 

        '''  

        dataMat = np.zeros((10,1))  

        label = []  

        for parent,dirnames,filenames in os.walk(dirName):  

            # print parent  

            # print dirnames  

            # print filenames  

            index = 0  

            for dirname in dirnames:  

                for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname):  

                    for filename in subFilenames:  

                        img = self.loadImg(subParent+'/'+filename,self.dsize)  

                        tempImg = np.reshape(img,(-1,1))  

                        IF index == 0 :  

                            dataMat = tempImg  

                        else:  

                            dataMat = np.column_stack((dataMat,tempImg))  

                        label.append(subParent+'/'+filename)  

                        index += 1  

        return dataMat,label  

  

  

    def PCA(self,dataMat,dimNum):  

        ''''' 

        PCA函數,用於數據降維 

        :param dataMat: 樣本矩陣 

        :param dimNum: 降維後的目標維度 

        :return: 降維後的樣本矩陣和變換矩陣 

        '''  

        # 均值化矩陣  

        meanMat = np.mat(np.mean(dataMat,1)).T  

        print u'平均值矩陣維度',meanMat.shape  

        diffMat = dataMat-meanMat  

        # 求協方差矩陣,由於樣本維度遠遠大於樣本數目,所以不直接求協方差矩陣,採用下面的方法  

        covMat = (diffMat.T*diffMat)/float(diffMat.shape[1]) # 歸一化  

        #covMat2 = np.cov(dataMat,bias=True)  

        #print '基本方法計算協方差矩陣為',covMat2  

        print u'協方差矩陣維度',covMat.shape  

        eigVals, eigVects = np.linalg.eig(np.mat(covMat))  

        print u'特徵向量維度',eigVects.shape  

        print u'特徵值',eigVals  

        eigVects = diffMat*eigVects  

        eigValInd = np.argsort(eigVals)  

        eigValInd = eigValInd[::-1]  

        eigValInd = eigValInd[:dimNum] # 取出指定個數的前n大的特徵值  

        print u'選取的特徵值',eigValInd  

        eigVects = eigVects/np.linalg.norm(eigVects,axis=0) #歸一化特徵向量  

        redEigVects = eigVects[:,eigValInd]  

        print u'選取的特徵向量',redEigVects.shape  

        print u'均值矩陣維度',diffMat.shape  

        lowMat = redEigVects.T*diffMat  

        print u'低維矩陣維度',lowMat.shape  

        return lowMat,redEigVects  

  

    def compare(self,dataMat,testImg,label):  

        ''''' 

        比較函數,這裡只是用了最簡單的歐氏距離比較,還可以使用KNN等方法,如需修改修改此處即可 

        :param dataMat: 樣本矩陣 

        :param testImg: 測試圖像矩陣,最原始形式 

        :param label: 標籤矩陣 

        :return: 與測試圖片最相近的圖像文件名 

        '''  

        testImg = cv2.resize(testImg,self.dsize)  

        testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY)  

        testImg = np.reshape(testImg,(-1,1))  

        lowMat,redVects = self.PCA(dataMat,self.dimNum)  

        testImg = redVects.T*testImg  

        print u'檢測樣本變換後的維度',testImg.shape  

        disList = []  

        testVec = np.reshape(testImg,(1,-1))  

        for sample in lowMat.T:  

            disList.append(np.linalg.norm(testVec-sample))  

        print disList  

        sortIndex = np.argsort(disList)  

        return label[sortIndex[0]]  

  

  

    def predict(self,dirName,testFileName):  

        ''''' 

        預測函數 

        :param dirName: 包含訓練數據集的文件夾路徑 

        :param testFileName: 測試圖像文件名 

        :return: 預測結果 

        '''  

        testImg = cv2.imread(testFileName)  

        dataMat,label = self.createImgMat(dirName)  

        print u'加載圖片標籤',label  

        ans = self.compare(dataMat,testImg,label)  

        return ans  

  

  

if __name__ == '__main__':  

    eigenface = EigenFace(200,500,(500,500))  

    print eigenface.predict('d:/face/11.bmp','D:/face1/1.bmp')  

免責聲明:本文轉自電子發燒友論壇,傳播僅為學習交流,版權歸原作者所有,如有侵權,請聯繫刪除

相關焦點

  • 人臉識別算法中的一些重要的算法
    這些算法的涉及面非常廣泛,包括模式識別、圖像處理、計算機視覺、人工智慧、統計學習、神經網絡、小波分析、子空間理論和流形學習等眾多學科。所以很難用一個統一的標準對這些算法進行分類。根據輸入數據形式的不同可分為基於靜態圖像的人臉識別和基於視頻圖像的人臉識別。因為基於靜態圖像的人臉識別算法同樣適用於基於視頻圖像的人臉識別,所以只有那些使用了時間信息的識別算法才屬於基於視頻圖像的人臉識別算法。
  • 使用Python+PCA+SVM算法實現人臉識別模型
    在本文中,我們將使用主成分分析和支持向量機來建立人臉識別模型
  • 深扒人臉識別60年技術發展史(附國內人臉識別科技企業名單)
    這一結果表明:大訓練數據集對於有效提升非受限環境下的人臉識別很重要。然而,以上所有這些經典方法,都難以處理大規模數據集的訓練場景。2014年前後,隨著大數據和深度學習的發展,神經網絡重受矚目,並在圖像分類、手寫體識別、語音識別等應用中獲得了遠超經典方法的結果。
  • AI大廠算法測試心得:人臉識別關鍵指標有哪些?
    由調查機構發布的《中國AI產業地圖研究》中也有一組有趣的數據,目前中國的AI企業中,有近8成集中在應用層,其中AI行業解決方案佔比高達40.7%,從上下班的人臉識別考勤,到金融App的人臉身份核驗,再到醫院和政務大廳的人臉識別取號,以及車站的人臉核驗檢票……  目前市面上既有OpenCV等開源算法庫,很多晶片廠商的產品也自帶簡單算法,同時專業算法大廠也會開放相關技術,
  • 人臉識別系列三 | MTCNN算法詳解上篇
    前言我們前面分享了PCA,Fisher Face,LBPH三種傳統的人臉識別算法,Dlib人臉檢測算法。今天我們開始分享一下MTCNN算法,這個算法可以將人臉檢測和特徵點檢測結合起來,並且MTCNN的級聯結構對現代的人臉識別也產生了很大的影響。上篇為大家介紹MTCNN的算法原理和訓練技巧,下篇為大家解析MTCNN算法的代碼和進行demo演示。
  • 重磅|中科視拓開源SeetaFace2人臉識別算法
    今天,來自中科院計算所的人工智慧國家隊中科視拓宣布,開源商用級SeetaFace2人臉識別算法。SeetaFace2採用商業友好的BSD協議,這是在2016年9月開源SeetaFace1.0人臉識別引擎之後,中科視拓在人臉識別領域的又一次自我革命。
  • 最先進的人臉識別算法:在口罩面前也不靈了
    本周一,美國標準化與技術研究所(NIST)公布最新發現,即便是最先進的人臉識別算法,面對戴口罩的被識別對象,會有至少5%的失敗率,遠超可被接受的0.3%失效率。人臉識別算法依賴於獲取儘可能多的數據點位,而佩戴口罩後,大量有價值的信息被帶走。
  • 百度人臉識別搜索是怎麼實現的?
    然而要把想法變為現實,百度至少要解決兩個問題:一是算法,二是數據。——算法方面。同樣是基於圖片進行搜索,人臉識別和以圖搜圖並不一樣。百度資深工程師陶吉告訴創事記,百度人臉識別首先並不關注完整的圖像結構,其次顏色也沒有任何意義。最主要的特徵表達來自於臉部紋理,並進行一些再加工。具體算法作為商業機密,難以對外界披露。
  • 人臉識別算法常用性能評價指標
    01算法性能測試要到實際場景中人臉識別算法的準確率是
  • 一文讀懂:深扒人臉識別60年技術發展史
    這一結果表明:大訓練數據集對於有效提升非受限環境下的人臉識別很重要。然而,以上所有這些經典方法,都難以處理大規模數據集的訓練場景。  2014年前後,隨著大數據和深度學習的發展,神經網絡重受矚目,並在圖像分類、手寫體識別、語音識別等應用中獲得了遠超經典方法的結果。
  • 基於深度學習的人臉識別算法
    基於深度學習的人臉識別算法,如何讓神經網絡從訓練數據中學習到有效、魯棒的生物特徵是至關重要的。
  • 人臉識別經典—FaceNet【美亞技術分享VOL.58】
    ,讓人臉識別、深度學習甚至是人工智慧顯得不再神秘,LFW識別率99%已經隨處可見,今天美亞柏科技術專家就人臉識別的一些經典算法和資源進行分享,感受大神們的「最強大腦」!在實際應用中,人臉驗證(判斷是否是同一人)、人臉識別(這個人是誰)和人臉聚類(尋找類似的人)在自然場景應用仍面臨一些困難。為了降低背景和環境等因素帶來的幹擾,人臉識別一般先經過人臉檢測(Face Detection)、人臉對齊(Face Alignment)等預處理,然後將人臉圖像映射到歐幾裡得等空間,空間距離的長度代表了人臉圖像的相似性。
  • 中國在人臉識別算法方面處於世界領先地位
    中國的人臉識別算法在世界上處於領先地位,其最好的算法能夠在不到一秒的時間內識別出一千萬人,而不會出現任何錯誤。美國商務部國家標準與技術研究院周五發布了2018年人臉識別測試結果,根據該測試,全球39種人臉識別算法中排名前五的均來自中國。
  • 人臉識別系統助力智慧校園,實現場景化、精細化管理
    人臉識別進出校園管理系統在校園門口等處安裝人臉識別通行閘機,「刷臉」識別系統方便快捷,在學生、教師及校園其他工作人員經過閘機時,學生站在閘機通道的攝像頭前,人臉對著機器一刷,不到1秒就可被準確識別出身份,自動進行人臉信息的抓取、驗證、核對,
  • 中科視拓開源SeetaFace2人臉識別算法
    集微網消息(文/春夏)近日,中科視拓(北京)科技有限公司(以下簡稱「中科視拓」)宣布,開源商用級SeetaFace2人臉識別算法。SeetaFace2支持的上層應用包括但不限於人臉門禁、無感考勤、人臉比對等。與2016年開源的SeetaFace1.0相比,SeetaFace2在速度和精度兩個層面上均有數量級的提升。
  • 人臉識別(一)——從零說起
    此系列文章將從理論到實踐進行整合:分三篇進行敘述,第一篇從零說人臉識別,保證大多數朋友能通過這篇文章了解到人臉識別的概念,並且能夠形成一個基本的框架。第二篇將進行初步的實踐,包括人臉圖像的採集,和如何利用opencv已有的模型根據人臉圖像進行訓練,得到需要的分類器。第
  • 人臉識別開發技巧揭秘
    隨著人臉識別終端設備的廣泛應用,很多開發者在實踐中會產生疑惑:為什麼同一款主板,運行性能相仿的算法時,系統資源佔用會相差懸殊?為什麼同樣配備了活體檢測,防攻擊能力卻可以差好幾個級別?事實上,人臉識別算法在實際部署中存在一些編程開發策略,能對識別效果和識別速度產生顯著影響。
  • 全民戴口罩,人臉識別算法抓瞎:多種算法出錯,最高錯誤率達50%
    而且,黑色口罩比藍色口罩更容易出錯,口罩遮住口鼻的範圍越大,算法就越難識別人臉。一些算法錯誤率高達50%NIST 計算機科學家、該研究報告的作者之一 Mei Ngan 說:「隨著新冠疫情的到來,我們想要了解人臉識別技術是如何處理帶口罩的面孔。我們首先關注的是,在疫情大流行之前開發的算法可能會因識別對象戴口罩而受到影響。
  • 人臉識別算法終於超過了人類本身 - OSCHINA - 中文開源技術交流社區
    計算機科學家已經開發出一種新的人臉識別算法,在識別人臉的能力上比人類本身更加強大。
  • 人臉識別最全知識圖譜
    目前常用中值濾波算法對人臉圖像進行預處理。圖像尺寸歸一化:在進行簡單的人臉訓練時候,遇到人臉庫的圖像像素大小不一樣時,我們需要在上位機人臉比對識別之前對圖像做尺寸歸一化處理。需要比較常見的尺寸歸一化算法有雙線性插值算法、最近鄰插值算法和立方卷積算法等。