使用Python,OpenCV,本地二进制模式(LBP)进行人脸识别
使用Python,OpenCV與本地二進制模式(LBP)進行人臉識別
- 1. 效果圖
- 2. 原理及步驟
- 2.1 原理
- 2.2 步驟
- 3. 源碼
- 參考
在深度學習和暹羅網絡之前,面部識別算法依賴于特征提取和機器學習。
這篇博客將介紹如何使用本地二進制模式(Local Binary Patterns LBP),OpenCV和CV2.Face.LbphFacerEgnizer_Create進行人臉識別功能。
1. 效果圖
2. 原理及步驟
2.1 原理
首先是應用CALTECH FACES數據集,這是評估面部識別算法的基準數據集。
然后審查了Ahonen等人介紹的LBPS面部識別算法。這種方法非常簡單且有效。整個算法基本上由三個步驟組成:
- 將每個輸入圖像的面部劃分為7×7等大小的單元格;
- 從每個單元中提取局部二進制模式。根據如何辨別每個細胞用于人臉識別來度量它們,最后連接7×7 = 49直方圖以形成最終特征向量;
- 使用具有k = 1的的K-NN分類器和x^2距離度量來執行面部識別。
在Caltech面對數據集上訓練臉部識別器,可獲得98%的準確性。
2.2 步驟
-
給定數據集中的面部,算法的第一步是將面部劃分為7×7等大小的單元。
-
然后,對于這些單元中的每一個,計算局部二進制模式直方圖。
根據定義,直方圖拋出關于模式如何彼此定向的空間信息。然而,通過計算每個小區域的直方圖,我們實際上能夠編碼諸如眼睛,鼻子,嘴巴等的空間信息水平。該空間編碼還允許我們以不同方式從每個細胞的直方圖中給出不同的加權值,表明更明顯的面部特征的差異。
可以看到原始的面部圖像分為7×7個細胞(左)。然后,在右側,我們可以看到每個單元的加權方案:
-
對于白色細胞(例如眼睛)的LBP直方圖比其他細胞更多的重量為4倍。這簡單意味著從白細胞區域采取LBP直方圖并將它們乘以4(考慮到直方圖的任何縮放/歸一化)。
淺灰色細胞(嘴巴和耳朵)貢獻2倍。
深灰色細胞(內頰和額頭)只有貢獻1x。
最后,黑細胞,如鼻子和外臉頰,完全忽略并稱重0x。
Ahonen等人通過在其訓練,驗證和測試數據拆分之上運行HyperParameter調整算法等實驗發現了這些加權值。
最后,加權的7×7 LBP直方圖連接在一起以形成最終特征向量。
- 執行面部識別是使用 x^2 距離和最近的鄰居分類器完成的:
-
臉部呈現給系統
-
以與訓練數據相同的方式提取,加權和連接的Lbps
-
使用 x^2 距離進行K-NN(帶k = 1),以找到訓練數據中最接近的面。
-
選擇最小的距離的臉部相關聯的人的名稱作為最終分類
用于面部識別算法的LBP并不復雜!提取局部二進制模式將提取方法擴展為計算7×7 = 49個細胞的直方圖是簡單的。
注意,面部識別算法的LBP具有可更新的額外益處,因為新的面部被引入數據集。
其他流行算法(例如特征缺口 EigenFaces)要求在訓練時間出現要識別的所有面孔。這意味著如果將新的面部添加到數據集中,則必須重新培訓整個特征文件分類器,這可以是非常重要的密集型的。
相反,用于面部識別算法的LBPS可以簡單地插入新的面部樣本,而無需重新培訓 - 在使用與常規頻率的數據集中添加或從數據集中刪除的面部數據集時顯而易見的益處。
3. 源碼
# CALTECH FACES是面部識別算法的基準數據集。總的來說,數據集由450個圖像組成約27人。如圖4所示,在各種照明條件,背景場景和面部表情下捕獲每個受試者。
# 本教程的總體目標是應用特征缺陷面部識別算法(Eigenfaces face recognition algorithm),以識別CALTECH FACES數據集中的每個拍攝對象。# face_detector 目錄包含OpenCV深度學習的面部探測器。該探測器既快速準確,能夠實時運行,無需GPU。# USAGE
# python lbp_face_reco.py --input caltech_faces# 導入必要的包
from sklearn.preprocessing import LabelEncoder # 加載類標簽由String轉為int類型
from sklearn.model_selection import train_test_split # 訓練和測試數據集分割
from sklearn.metrics import classification_report
from pyimagesearch.faces import load_face_dataset # 加載CaltechFaces數據集
import numpy as np
import argparse
import imutils
import time
import cv2
import os# 構建命令行參數及解析
# --input 輸入圖片數據集的路徑
# --face 面部檢測器模型的目錄
# --confidence 面部檢測的最小置信度(用于標識弱/假陽性結果的值)
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", type=str, required=True,help="path to input directory of images")
ap.add_argument("-f", "--face", type=str,default="face_detector",help="path to face detector model directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5,help="minimum probability to filter weak detections")
args = vars(ap.parse_args())# 從磁盤加載序列化的面部檢測器模型
print("[INFO] loading face detector model...")
prototxtPath = os.path.sep.join([args["face"], "deploy.prototxt"])
weightsPath = os.path.sep.join([args["face"],"res10_300x300_ssd_iter_140000.caffemodel"])
net = cv2.dnn.readNet(prototxtPath, weightsPath)# 加載CALTECH faces數據集,要求置信度0.5,每個人最小樣本量20
print("[INFO] loading dataset...")
(faces, labels) = load_face_dataset(args["input"], net,minConfidence=0.5, minSamples=20)
print("[INFO] {} images in dataset".format(len(faces)))# 編碼類標簽由String轉為Int
le = LabelEncoder()
labels = le.fit_transform(labels)# 構建訓練和測試集分組(訓練集75%,測試集25%)
(trainX, testX, trainY, testY) = train_test_split(faces,labels, test_size=0.25, stratify=labels, random_state=42)# 訓練LBP面部識別器
print("[INFO] training face recognizer...")
# 雖然Ahonen等人的原始訓練建議使用7×7網格,我更喜歡使用8×8網格,允許更高的粒度,從而提高準確度。
# 這種準確度的提高是以(1)更長的特征提取/比較時間(由于將從49到64跳躍的LBP直方圖的數量)為代價(由于從49到64跳躍),但也許更重要的是,(2)相當多的內存消耗存儲特征向量。
# 在實踐中,自己的數據集上您應該調整grid_x和grid_y,并查看哪些值產生最高準確度。
recognizer = cv2.face.LBPHFaceRecognizer_create(radius=2, neighbors=16, grid_x=8, grid_y=8)
start = time.time()
# 訓練模型
recognizer.train(trainX, trainY)
end = time.time()
print("[INFO] training took {:.4f} seconds".format(end - start))# 初始化預測結果和置信度list
print("[INFO] gathering predictions...")
predictions = []
confidence = []
start = time.time()# 遍歷測試數據集
for i in range(0, len(testX)):# 執行面部識別預測# 更新預測list和置信度分數list# 返回(1)預測的2元組(即主題的整數標簽)和(2)CONF(信心短暫),它只是當前測試矢量和訓練數據中最近的數據點之間的x^2距離。距離越低,兩個面部屬于同一個人的可能性越大。(prediction, conf) = recognizer.predict(testX[i])predictions.append(prediction)confidence.append(conf)# 度量預測數據集耗時
end = time.time()
print("[INFO] inference took {:.4f} seconds".format(end - start))# 展示分類結果
print(classification_report(testY, predictions,target_names=le.classes_))# 生成測試數據的樣本
idxs = np.random.choice(range(0, len(testY)), size=10, replace=False)# 便利測試數據樣本
for i in idxs:# 獲取預測面部名稱和實際名稱predName = le.inverse_transform([predictions[i]])[0]actualName = le.classes_[testY[i]]# 獲取面部圖片并等比例縮放為寬度250,因此可以很好的展示在屏幕上face = np.dstack([testX[i]] * 3)face = imutils.resize(face, width=250)# 顯示預測名稱和實際名稱在圖像上cv2.putText(face, "pred: {}".format(predName), (5, 25),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)cv2.putText(face, "actual: {}".format(actualName), (5, 60),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)# 展示預測名稱,實際名稱,預測置信度文本值在圖像上,預測置信度值越小,預測越準確;print("[INFO] prediction: {}, actual: {}, confidence: {:.2f}".format(predName, actualName, confidence[i]))# 顯示面部到屏幕cv2.imshow("Face", face)cv2.waitKey(0)
參考
- https://www.pyimagesearch.com/2021/05/03/face-recognition-with-local-binary-patterns-lbps-and-opencv/
- FaceNet
盡管近期識別領域發展迅速,但在規模上有效地實施面部核查和識別會對目前的方法產生嚴重挑戰。在本文中,我們提出了一個稱為FaceNet的系統。該系統直接從面部圖像到緊湊的歐幾里德空間學習,其中距離直接對應于面部相似度的量度。一旦產生了該空間,可以使用具有FaceNet Embeddings作為特征向量的標準技術來容易地實現諸如面部識別,驗證和聚類的任務。
我們使用深度卷積的網絡訓練,直接優化嵌入本身,而不是在以前的深度學習方法中的中間瓶頸層。訓練模型時我們使用小說在線三聯挖掘方法產生的大致對齊/非匹配面補丁的三胞胎。這個方法的好處是更大的代表性效率:僅利用每張面部128字節實現最先進的面部識別性能。
在被廣泛使用的Wild(LFW)數據集中,FaceNet系統實現了99.63%的新記錄準確度。在YouTube面部DB數據集中,它達到了95.12%。我們的系統與兩個數據集中的最佳已發布結果相比削減了錯誤率。
我們還介紹了諧波嵌入以及諧波三態損失的概念,描述了彼此兼容的不同版本的面部嵌入式(由不同的網絡產生),并且允許彼此之間的直接比較。
- OpenFace
OpenFace是一個Python和 Torch 的人臉識別與深神經網絡的人臉識別,并基于CVPR 2015紙張面孔:谷歌·施羅夫,德米特里卡萊尼科和詹姆斯菲爾賓的面部識別和聚類統一嵌入。Torch 允許在CPU或CUDA上執行網絡。
使用深神經網絡表示(或嵌入)128維單元間距的面部。嵌入是通用的操作。與其他面部表示不同,這種嵌入具有良好的特性,即兩個面部嵌入之間的距離更大的距離意味著面部可能不具有同一個人。該屬性使得聚類,相似性檢測和分類任務更容易。
總結
以上是生活随笔為你收集整理的使用Python,OpenCV,本地二进制模式(LBP)进行人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 308激光多少钱啊?
- 下一篇: 使用Python,OpenCV的Mean