人臉識別是通過視頻采集設備獲取用戶的面部圖像,然後利用核心算法對人臉的面部位置、臉型、角度進行計算分析,再與自身數據庫中已有的模板進行比對,進而判斷用戶的真實身份。
人臉識別算法是指在檢測到人臉,定位到人臉的關鍵特征點後,經過預處理,可以切出主要的人臉區域,送入後端的識別算法。識別算法要完成人臉特征的提取,並與庫存中的已知人臉進行比較,完成最終的分類。
人臉識別算法有四種:基於人臉特征點的識別算法、基於整張人臉圖像的識別算法、基於模板的識別算法和基於神經網絡的識別算法。
人臉識別算法原理;
系統的輸入壹般是壹幅或壹系列身份未定的人臉圖像,以及人臉數據庫中若幹幅身份已知或對應編碼的人臉圖像,而輸出則是壹系列相似度得分,表示待識別人臉的身份。
人臉識別的三種經典算法
1,特征臉(Eigenfaces)算法
Eigenfaces是在人臉識別的計算機視覺問題中使用的壹組特征向量的名稱。特征臉是基於PCA(主成分分析)的,所以學習特征臉需要我們了解PCA的原理。
基本思想
主成分分析(PCA)是壹種矩陣壓縮算法,可以降低矩陣的維數,盡可能保留原矩陣的信息。簡單來說,就是把n×m的矩陣轉換成n×k的矩陣,只保留矩陣的主要特征,從而大大節省空間和數據。PCA的實現需要降維,即將矩陣從高維轉換到低維。然而,PCA的降維離不開協方差矩陣。方差描述的是壹維數據樣本與均值的偏差,是壹種用來衡量兩個隨機變量之間關系的統計量。從角度上看,角度越小,數值越大,方向越近,即正相關越多。協方差矩陣度量的不僅僅是兩個隨機變量之間的關系,更是維度之間的關系,而不是樣本之間的關系。
學習壹個新事物,尤其是知識,需要了解知識中的思想。我在理解和學習特征臉算法的時候,它的思想是圖像識別首先要選擇壹個合適的子空間,把所有的圖像集中在這個子空間裏,然後在這個子空間裏進行相似度的度量或者進行分類學習,然後再談子空間到另壹個空間的變換。這有以下作用:壹是同類的圖像更近,二是不同類的圖像更遠;這樣,通過線性分類分離的圖像可以很容易地在新的空間中分離。同時,特征人臉技術會找到人臉圖像分布的基本元素,即人臉圖像樣本集的協方差矩陣的特征向量,以此來表征人臉圖像。人臉圖像的基本元素有很多,比如眼睛、臉頰、嘴唇等基本元素。這些特征向量在特征臉的圖像空間中生成的子空間稱為子臉空間。
子空間生成後,就要構造空間,那麽如何構造空間呢?首先要尋找人臉的* * *其次要尋找個體和* * *的區別最後要明白* * *其實是壹個空間,個體是壹個矢量。利用協方差矩陣對目標集中所有人臉圖像的特征值進行分解,得到相應的特征向量。這些特征向量就是“特征面”。求特征向量的特征,線性組合。在基於每個特征子面的空間中,每個面都是壹個點,這個點的坐標就是每個面在每個特征基下的投影坐標。
特征臉算法過程
獲取人臉圖像數據,將每個人臉圖像矩陣按行串成壹維,每個人臉為壹個向量;
把對應維度的M張臉加起來,然後平均,得到“平均臉”;
從每個圖像中減去平均人臉向量;
計算協方差矩陣;
基於特征臉記憶的人臉識別:
算法練習流程;
訓練圖像
找到平均臉
獲取特征子面
執行圖像重建。
尋找相似度高的人臉圖像。
2.FisherFace算法
FisherFace是Fisher線性判別式在人臉識別中的應用。線性判別分析(LDA)算法的思想最早是由英國統計學家和遺傳學家、現代統計科學的奠基人之壹羅納德提出的。LDA算法利用統計方法,試圖找到對象之間特征的線性組合,在降維的同時考慮類別信息。該算法得到的線性組合可以用作線性分類器或降維。
基本思想
線性判別分析的基本思想是將高維模式樣本投影到低維最優向量空間,從而提取重要的分類信息,壓縮特征空間的維數。投影後的模式樣本保證在新的子空間中具有最大的類間距離和最小的類內距離,即模式在這個空間中具有最好的可分性。特征臉中使用的理論和特征臉有相似之處,都是將原始數據的全維降低到低維空間的方法。在從整個數據中提取局部紋理特征方面,fisherfaces和Eigenfaces不同於LBP。
利用Fisher線性判別方法確定壹個最優投影方向,構造壹維符號空間,將多維人臉圖像投影到fisherfaces特征空間,利用類內樣本數據形成壹組特征向量,代表人臉的特征。
我們知道,該算法在樣本數據映射到另壹個特征空間後,最小化類內距離,最大化類間距離。LDA算法可以用於降維,其原理與PCA算法非常相似,因此LDA算法也可以用於人臉識別領域。使用PCA算法進行人臉識別的算法稱為特征臉方法,而使用LDA算法進行人臉識別的算法稱為Fisher人臉方法。
與PCA相比,LDA:
相同:1。兩者在降維時都采用了矩陣的特征分解思想;2.兩者都假設數據符合高斯分布。區別:1和LDA是有監督的降維方法,PCA是無監督的。2.如果數據是K維的,那麽LDA只能降維到(k-1)維,而PCA則不受此限制。3.從數學角度看,LDA選擇分類性能最好的投影方向,PCA選擇樣本投影點方差最大的方向。與特征臉算法相比,Fisherfaces算法:
相同:兩者都可以降低數據的維度;兩者都在降維中使用了矩陣特征分解的思想。
不同:Fisherfaces是有監督的降維方法,而Eigenfaces是無監督的降維方法;Fisherfaces不僅可以用於降維,還可以用於分類。
值得壹提的是,FisherFace算法的錯誤率低於哈佛和耶魯人臉庫測試的特征臉識別結果。
Fisherface算法流程
獲取人臉圖像數據,然後計算人臉的平均值。
觀察每張臉的特征值。
進行人臉識別,觀察面部特征,判斷是否為個人。
最後進行人臉識別。
3.LBPH(局部二元模式直方圖)算法
局部二值模式直方圖是LBP特征的統計直方圖,LBPH結合了LBP特征和圖像的空間信息。如果LBP編碼圖像直接用於人臉識別。其實提取LBP特征和不提取LBP特征差別不大。因此,在實際的LBP應用中,壹般采用LBP編碼圖像的統計直方圖作為分類識別的特征向量。
最初的LBP算子被定義為將33°窗口內的八個相鄰像素的灰度值與作為閾值的窗口的中心像素進行比較。如果外圍像素值大於等於中心像素值,則像素點的位置標記為1,否則為0。這樣就可以比較33鄰域內的8個點,生成8位二進制數(通常轉換成十進制數,即LBP碼,***256種),即可以得到窗口中心像素點的LBP值,這個值可以用來反映這個區域的紋理特征。
LBPH的尺寸:有8個采樣點。如果使用原始LBP或擴展LBP特征,則壹幅圖像的LBP特征向量維數為:64256=16384維,而如果使用UniformPatternLBP特征,則LBP值有59個模式。其特征向量的維數為:6459=3776。可以看出,使用等價模式特征大大降低了其特征向量的維數,這意味著使用機器學習方法的學習時間會大大減少,但性能不會受到太大影響。
基本思想
基於LBPH的人臉識別方法的基本思想是:首先以每個像素為中心,判斷與周圍像素灰度值的關系,並進行二進制編碼,從而得到整幅圖像的LBP編碼圖像;然後將LBP圖像劃分為四個區域,得到每個區域的LBP編碼直方圖,進而得到整幅圖像的LBP編碼直方圖。通過比較不同人臉圖像的LBP編碼直方圖,達到人臉識別的目的。它的優點是不受光照、縮放、旋轉和平移的影響。
顧名思義,LBPH算法采用局部特征提取的方法,這是與前兩種方法最大的區別。
算法流程
LBP特征提取:根據統壹的LBP算子對原始圖像進行處理;
LBP特征匹配(直方圖計算):將圖像分成若幹子區域,根據子區域內的LBP值統計其直方圖,以直方圖作為其區別特征。
4.算法的復制代碼
1),特征臉算法。
#編碼=utf-8
將numpy作為np導入
導入cv2
導入操作系統
類別特征面(對象):
def __init__(self,threshold,dimNum,dsize):
self . threshold = threshold # threshold尚未使用。
self.dimNum = dimNum
self.dsize = dsize
def loadImg(自身,文件名,尺寸):
'''
加載圖像,灰度化,統壹大小,直方圖均衡化。
:param fileName:圖像文件名
:paramsize:統壹大小。元組形式
:返回:圖像矩陣
'''
img = cv2.imread(文件名)
retImg = cv2.resize(img,dsize)
retImg = cv2.cvtColor(retImg,cv2。彩色_ RGB 2灰色)
retImg = cv2.equalizeHist(retImg)
# cv2.imshow('img ',retImg)
# cv2.waitKey()
返回重定位
def createImgMat(self,dirName):
'''
生成圖像樣本矩陣,該矩陣被組織為行為屬性並作為樣本列出。
:param dirName:包含訓練數據集的圖像文件夾的路徑。
:返回:樣本矩陣,標簽矩陣
'''
dataMat = np.zeros((10,1))
label = []
對於父目錄,目錄名,os.walk中的文件名(目錄名):
#打印父項
#打印目錄名
#打印文件名
指數= 0
對於目錄名中的目錄名:
對於os.walk中的子父項、子文件名、子文件名(父+'/'+目錄名):
對於子文件名中的文件名:
img = self . load img(sub pent+'/'+filename,self.dsize)
tempImg = NP . shape(img,(-1,1))
如果索引== 0:
dataMat = tempImg
否則:
dataMat = NP . column _ stack((dataMat,tempImg))
label.append(子部分+'/'+文件名)
指數+= 1
返回數據表,標簽
def PCA(self,dataMat,dimNum):
'''
PCA函數,用於數據降維。
:param dataMat:樣本矩陣
:param dimNum:降維後的目標維度。
:返回:降維後的樣本矩陣和變換矩陣。
'''
#平均矩陣
meanMat = np.mat(np.mean(dataMat,1))。T
打印'平均矩陣尺寸',表示矩陣形狀
diffMat = dataMat-meanMat
#求協方差矩陣,因為樣本維數遠大於樣本數,所以不要直接求協方差矩陣,采用以下方法。
cov mat =(diff mat . t * diff mat)/float(diff mat . shape[1])#規範化
#covMat2 = np.cov(dataMat,bias=True)
# print '基本方法計算的協方差矩陣是',covMat2。
打印“協方差矩陣維數”,covMat.shape
eigVals,EIG vects = NP . linalg . EIG(NP . mat(cov mat))
打印“特征向量維數”,特征向量。形狀
打印“特征值”,特征值
eigVects = diffMat*eigVects
eigValInd = np.argsort(eigVals)
EIG valind = EIG valind[::-1]
EigValInd = eigValInd[:dimNum] #取出指定數字的前n個特征值。
打印“選定特征值”,eigValInd
EIG vectors = EIG vectors/NP . linalg . norm(EIG vectors,axis = 0) #歸壹化特征向量
redeigwects = EIG vects[:,eigValInd]
打印“選定的特征向量”,重新設計向量。形狀
打印'平均矩陣維數',差異矩陣形狀
lowMat = redEigVects。t *差分格式
打印'低維矩陣維度',lowMat.shape
返回lowMat,重新設計
定義比較(自身、數據、測試、標簽):
'''
比較函數,這裏只使用最簡單的歐幾裏德距離比較,還可以使用KNN等方法,如果需要在這裏修改的話。
:param dataMat:樣本矩陣
:參數測試:原始形式的測試圖像矩陣。
:參數標簽:標簽矩陣
:return:與測試圖像最接近的圖像文件名。
'''
testImg = cv2.resize(testImg,self.dsize)
testImg = cv2.cvtColor(testImg,cv2。彩色_ RGB 2灰色)
testImg = NP . shape(testImg,(-1,1))
lowMat,redVects = self。PCA(dataMat,self.dimNum)
testImg = redVects。t *測試
打印“檢測樣品的轉換尺寸”,testimg.shape。
disList = []
testVec = NP . shape(testImg,(1,-1))
適用於lowMat中的樣品。t:
dislist . append(NP . linalg . norm(test vec-sample))
打印列表
sortIndex = np.argsort(disList)
返回標簽[sortIndex[0]]
定義預測(自身,目錄名,測試文件名):
'''
預測功能
:param dirName:包含定型數據集的文件夾的路徑。
:param testFileName:測試圖像文件名。
:返回:預測結果
'''
testImg = cv2 . im read(test filename)
dataMat,label = self.createImgMat(目錄名)
打印“加載圖片標簽”,標簽
ans = self.compare(數據、測試、標簽)
返回答案
if __name__ == '__main__ ':
eigenface = EigenFace(20,50,(50,50))
打印特征臉。Predict ('d:/face ',' d:/face _ test/1。BMP') 2)、FisherFaces算法。
#編碼=utf-8
將numpy作為np導入
導入cv2
導入操作系統
類FisherFace(對象):
def __init__(self,threshold,k,dsize):
self . threshold = threshold # threshold,尚未使用。
Self.k = k #指定投影的數量w。
Self.dsize = dsize #統壹大小
def loadImg(自身,文件名,尺寸):
'''
加載圖像,灰度化,統壹大小,直方圖均衡化。
:param fileName:圖像文件名
:paramsize:統壹大小。元組形式
:返回:圖像矩陣
'''
img = cv2.imread(文件名)
retImg = cv2.resize(img,dsize)
retImg = cv2.cvtColor(retImg,cv2。彩色_ RGB 2灰色)
retImg = cv2.equalizeHist(retImg)
# cv2.imshow('img ',retImg)
# cv2.waitKey()
返回重定位
def createImgMat(self,dirName):
'''
生成圖像樣本矩陣,該矩陣被組織為行為屬性並作為樣本列出。
:param dirName:包含訓練數據集的圖像文件夾的路徑。
:返回:包含樣本矩陣的列表,標簽列表
'''
dataMat = np.zeros((10,1))
label = []
數據列表= []
對於父目錄,目錄名,os.walk中的文件名(目錄名):
#打印父項
#打印目錄名
#打印文件名
#index = 0
對於目錄名中的目錄名:
對於os.walk中的子父項、子文件名、子文件名(父+'/'+目錄名):
對於索引,枚舉中的文件名(子文件名):
img = self . load img(sub pent+'/'+filename,self.dsize)
tempImg = NP . shape(img,(-1,1))
如果索引== 0:
dataMat = tempImg
否則:
dataMat = NP . column _ stack((dataMat,tempImg))
dataList.append(數據材質)
label.append(子部分)
返回數據列表,標簽
def LDA(self,dataList,k):
'''
多分類問題的線性判別分析算法
:參數數據列表:樣本矩陣列表
:param k:投影向量的數量k
:返回:轉換後的矩陣列表和轉換後的矩陣。
'''
n =數據列表[0]。形狀[0]
W = np.zeros((n,self.k))
Sw = np.zeros((n,n))
Sb = np.zeros((n,n))
u = np.zeros((n,1))
N = 0
meanList = []
sampleNum = []
對於dataList中的dataMat:
meanMat = np.mat(np.mean(dataMat,1))。T
meanList.append(meanMat)
sample num . append(datamat . shape[1])
dataMat = dataMat-meanMat
sw =數據矩陣*數據矩陣。T
軟件+=軟件
打印“軟件尺寸”,軟件形狀
對於索引,枚舉中的mean mat(mean list):
m = sample num[索引]
u += m*meanMat
N += m
u = u/N
打印“u形的尺寸”
對於索引,枚舉中的mean mat(mean list):
m = sample num[索引]
sb = m*(meanMat-u)*(meanMat-u)。T
Sb += sb
打印“某人的尺寸”,某人的形狀
eigVals,EIG vects = NP . Lina LG . EIG(NP . mat(NP . Lina LG . inv(Sw)* Sb))
eigValInd = np.argsort(eigVals)
EIG valind = EIG valind[::-1]
EigValInd = eigValInd[:k] #取指定個數的前k個特征值。
打印“選定特征值”,特征值有效。形狀
EIG vectors = EIG vectors/NP . linalg . norm(EIG vectors,axis = 0) #歸壹化特征向量
redeigwects = EIG vects[:,eigValInd]
打印“轉換矩陣維度”,重定向。形狀
transMatList = []
對於dataList中的dataMat:
trans matlist . append(redeig vects。T*dataMat)
返回transMatList,redEigVects
定義比較(自身、數據列表、測試、標簽):
'''
比較函數,這裏只使用最簡單的歐幾裏德距離比較,還可以使用KNN等方法,如果需要在這裏修改的話。
:參數數據列表:樣本矩陣列表
:參數測試:原始形式的測試圖像矩陣。
:參數標簽:標簽矩陣
:return:最接近測試圖像的圖像文件夾,即類別。
'''
testImg = cv2.resize(testImg,self.dsize)
testImg = cv2.cvtColor(testImg,cv2。彩色_ RGB 2灰色)
testImg = NP . shape(testImg,(-1,1))
transMatList,redVects = fisherface。LDA(數據表,self.k)
testImg = redVects。t *測試
打印“檢測樣品的轉換尺寸”,testimg.shape。
disList = []
testVec = NP . shape(testImg,(1,-1))
sum vec = NP . mat(NP . zeros((self . dsize[0]* self . dsize[1],1)))
對於transMatList中的transMat:
用於transMat中的樣品。t:
dislist . append(NP . linalg . norm(test vec-sample))
打印列表
sortIndex = np.argsort(disList)
返回標簽[sortIndex[0]/9]
定義預測(自身,目錄名,測試文件名):
'''
預測功能
:param dirName:包含定型數據集的文件夾的路徑。
:param testFileName:測試圖像文件名。
:返回:預測結果
'''
testImg = cv2 . im read(test filename)
dataMat,label = self.createImgMat(目錄名)
打印“加載圖片標簽”,標簽
ans = self.compare(數據、測試、標簽)
返回答案
if __name__=="__main__ ":
fisherface = FisherFace(10,20,(20,20))
ans = fisher face . predict(' d:/face ',' d:/face_test/8.bmp ')
打印ans3),LBPH算法
#編碼=utf-8
將numpy作為np導入
導入操作系統
導入cv2
LBP類(對象):
def __init__(self,threshold,dsize,blockNum):
Self.dsize = dsize #統壹大小
Self.blockNum = blockNum #劃分的塊數
self . threshold = threshold # threshold,尚未使用。
def loadImg(自身,文件名,尺寸):
'''
加載圖像,灰度化,統壹大小,直方圖均衡化。
:param fileName:圖像文件名
:paramsize:統壹大小。元組形式
:返回:圖像矩陣
'''
img = cv2.imread(文件名)
retImg = cv2.resize(img,dsize)
retImg = cv2.cvtColor(retImg,cv2。彩色_ RGB 2灰色)
retImg = cv2.equalizeHist(retImg)
# cv2.imshow('img ',retImg)
# cv2.waitKey()
返回重定位
def loadImagesList(self,dirName):
'''
加載圖像矩陣列表
:param目錄名:文件夾路徑
:返回:包含最原始圖像矩陣的列表和標簽矩陣。
'''
imgList = []
label = []
對於父目錄,目錄名,os.walk中的文件名(目錄名):
#打印父項
#打印目錄名
#打印文件名
對於目錄名中的目錄名:
對於os.walk中的子父項、子文件名、子文件名(父+'/'+目錄名):
對於子文件名中的文件名:
img = self . load img(sub pent+'/'+filename,self.dsize)
ImgList.append(img) #原始圖像矩陣被添加到列表中,不做任何處理。
label.append(子部分+'/'+文件名)
返回imgList,標簽
def getHopCounter(self,num):
'''
計算二進制序列是否只改變兩次。
:參數編號:編號
:return: 01更改次數
'''
binNum = bin(數量)
binStr = str(binNum)[2:]
n = len(binStr)
如果n =中心)*(1擴展知識:人臉識別算法研究的難點
人臉識別算法的研究由來已久,大多數算法在背景簡單的情況下都能很好的處理。但是人臉識別的應用範圍很廣,而且只是簡單的圖像測試,遠遠不能滿足實際需求。所以人臉識別算法還有很多難點。
照明
光照是機器視覺,尤其是人臉識別中的老問題,算法還沒到能用的程度。
態度
與光照問題類似,姿態問題也是人臉識別研究中需要解決的技術難點。對姿態的研究相對較少,大多數人臉識別算法主要是針對正面或接近正面的人臉圖像。當俯仰或者左右嚴重時,人臉識別算法的識別率也會急劇下降。
避難所
遮擋對於非合作條件下的人臉圖像采集來說是壹個非常嚴重的問題,尤其是在監控環境中,被監控對象經常佩戴眼鏡、帽子等飾品,可能會使采集到的人臉圖像不完整,從而影響後期的特征提取和識別,甚至導致人臉識別算法的失敗。
年齡變化
隨著年齡的變化,面部容貌也在發生變化,尤其是青少年,這種變化更為明顯。對於不同的年齡段,人臉識別算法的識別率是不同的。
圖像質量
人臉圖像的來源可能多種多樣,由於采集設備的不同,獲得的人臉圖像質量也不盡相同,特別是對於那些分辨率低、噪聲大、質量差的人臉圖像,如何有效地識別人臉是壹個需要關註的問題。同樣,對於高分辨率圖像,對人臉識別算法的影響需要進壹步研究。
缺少樣品
基於統計學習的人臉識別算法是人臉識別領域的主流算法,但是統計學習方法需要大量的訓練。由於人臉圖像在高維空間的分布是壹種不規則的流行分布,所以能夠得到的樣本只是人臉圖像空間中很小的壹部分。如何解決小樣本下的統計學習問題,需要進壹步研究。
海量數據
傳統的人臉識別算法如PCA和LDA可以很容易地在小規模數據中訓練和學習。但是,對於大量的數據,這些方法的訓練過程是困難的,甚至可能崩潰。
大規模人臉識別
隨著人臉數據庫的增長,人臉算法的性能會下降。