本文通過學(xué)習(xí)LBPH人臉識(shí)別算法,簡(jiǎn)要了解人臉識(shí)別技術(shù)的原理,實(shí)現(xiàn)人臉采集、訓(xùn)練人臉模型實(shí)現(xiàn)人臉識(shí)別。
一、 LBPH人臉識(shí)別算法概述
OpenCV庫(kù)自帶的人臉級(jí)聯(lián)分級(jí)器具有很好的人臉檢測(cè)和人臉追蹤效果,它是一個(gè)基于Haar特征的Adaboost級(jí)聯(lián)分類器。特別注意,OpenCV庫(kù)雖然自帶人臉級(jí)聯(lián)分級(jí)器,但是識(shí)別效率一般。本項(xiàng)目使用的是OpenCV提供的人臉識(shí)別算法LBPH(Local Binary Pattern Histogram),即局部二進(jìn)制模式直方圖,它屬于OpenCV拓展庫(kù)opencv-contrib的一部分,需要另外單獨(dú)安裝opencv-contrib-python-4.1.2。
LBPH人臉識(shí)別算法思路如下:將檢測(cè)到的人臉分為小單元如下圖1所示,并將其與模型中的對(duì)應(yīng)單元進(jìn)行比較,對(duì)每個(gè)區(qū)域的匹配值產(chǎn)生一個(gè)直方圖,如圖2所示,通過對(duì)直方圖的比較,算法將能夠識(shí)別圖像的邊緣和角,能夠識(shí)別直方圖中哪些代表人的主要特征,比如眼睛的顏色、嘴巴的形狀等等,這個(gè)算法的基本理論也就是基于直方圖的創(chuàng)建和比較。由于這種方法通過比較不同人臉圖像LBP編碼直方圖達(dá)到人臉識(shí)別的目的,其優(yōu)點(diǎn)是不會(huì)受到光照、縮放、旋轉(zhuǎn)和平移的影響。
提示:二進(jìn)制是將中間的數(shù)值“90”與四周數(shù)值進(jìn)行對(duì)比,大于為1,小于為0,然后繞四周逆時(shí)針得出二進(jìn)制10001101
*參考文檔:
1.使用LBPH算法理解人臉識(shí)別
2.LBPH人臉識(shí)別
二、 人臉識(shí)別技術(shù)原理
一個(gè)完整的人臉識(shí)別系統(tǒng)包含五個(gè)主要部分,即人臉采集(Face Collect)、人臉檢測(cè)(Face Detection)、人臉配準(zhǔn)(Face Alignment)、人臉特征提?。‵ace Feature Extraction)、人臉識(shí)別(Face Recognition)。
人臉采集:
利用攝像機(jī)等采集設(shè)備拍攝人臉圖像。
人臉檢測(cè):
人臉檢測(cè)是檢測(cè)出圖像中人臉?biāo)谖恢玫囊豁?xiàng)技術(shù),一般情況下就是用一個(gè)矩形框把人臉框出來。本項(xiàng)目使用Haar人臉識(shí)別分類器檢測(cè)。
人臉配準(zhǔn):
人臉配準(zhǔn)是根據(jù)輸入的人臉圖像,自動(dòng)定位出人臉上五官關(guān)鍵點(diǎn)坐標(biāo)的一項(xiàng)技術(shù),一般有5點(diǎn)、68點(diǎn)、90點(diǎn)。
人臉特征提?。?/strong>
人臉特征提取是將一張人臉圖像轉(zhuǎn)化為一串固定長(zhǎng)度的數(shù)值的過程。
人臉識(shí)別:
人臉識(shí)別是一種識(shí)別出輸入人臉圖對(duì)應(yīng)身份的算法技術(shù)。輸入一張人臉圖像,通過與注冊(cè)在庫(kù)中N個(gè)身份對(duì)應(yīng)的特征進(jìn)行逐個(gè)比對(duì),找出“一個(gè)”與輸入特征相似度最高的特征。
三、 關(guān)鍵模塊
1.根據(jù)以上分析,本項(xiàng)目將實(shí)現(xiàn)人臉識(shí)別分為以下3個(gè)小任務(wù),通過3個(gè)步驟來完成人臉采集與檢測(cè)、人臉模型訓(xùn)練、人臉識(shí)別。
2.函數(shù)介紹
在OpenCV中,使用函數(shù)cv2.face.LBPHFaceRecognizer_create()生成LBPH人臉識(shí)別器實(shí)例模型,然后應(yīng)用cv2.face_FaceRecognizer.train()函數(shù)完成訓(xùn)練,最后用cv2.face_FaceRecognizer.predict()函數(shù)完成人臉識(shí)別。
四、 實(shí)驗(yàn)準(zhǔn)備
1. 第三方庫(kù)
2. 新建相關(guān)文件夾
新建一個(gè)FaceRecognition工程文件夾,在里面Facedata文件夾、cv2data文件夾、Model文件夾
3. 實(shí)驗(yàn)環(huán)境
(1)攝像頭設(shè)備。
(2) python3.7(文末提供的安裝包是3.7版本的,如果是其他版本,請(qǐng)根據(jù)需要升級(jí)第三方庫(kù))。
備注:文末提供參考程序
五、 人臉采集與檢測(cè)實(shí)現(xiàn)
1.人臉采集與檢測(cè)FaceCollect.py代碼
(實(shí)現(xiàn)效果見本程序后面)
import cv2
import numpy as np
import random
# 將捕獲照片的大小裁剪為正方形
def getpaddingSize(shape):
# 照片的長(zhǎng)和寬
h, w = shape
longest = max(h, w)
# 將最長(zhǎng)的邊進(jìn)行處理
result = (np.array([longest]*4, int) - np.array([h, h, w, w], int)) // 2
return result.tolist()
# 圖像去噪處理,使得訓(xùn)練出來的模型具備一定的泛化能力
def dealwithimage(img, h=64, w=64):
top, bottom, left, right = getpaddingSize(img.shape[0:2])
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
img = cv2.resize(img, (h, w))
return img
# 改變亮度與對(duì)比度
def relight(imgsrc, alpha=1, bias=0):
imgsrc = imgsrc.astype(float)
imgsrc = imgsrc * alpha + bias
imgsrc[imgsrc < 0] = 0
imgsrc[imgsrc > 255] = 255
imgsrc = imgsrc.astype(np.uint8)
return imgsrc
# 捕獲人臉
def GetFace(name,face_id):
# 0: 筆記本內(nèi)置攝像頭; 1: USB攝像頭
camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 獲取分類器
face_detector = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')
count = 1
while True:
# 默認(rèn)獲取100張圖片作為訓(xùn)練數(shù)據(jù)集
if(count<=100):
print("It's processing %s image." % count)
# 讀取圖片
success,img = camera.read()
# 圖片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 檢測(cè)人臉
faces = face_detector.detectMultiScale(gray,1.31,2)
for (x, y, w, h) in faces:
# 圖像預(yù)處理,處理成64*64大小的圖片
face = gray[y:y+h, x:x+w]
face = cv2.resize(face, (64, 64))
# 圖像去噪處理
face = dealwithimage(face)
# 改變亮度與對(duì)比度
#face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
# 保存圖片
cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', face)
# 在圖片上顯示名字
cv2.putText(img, name, (x, y-20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
# 畫一個(gè)矩形
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
count+=1
cv2.imshow('img', img)
# 保持畫面持續(xù)
key = cv2.waitKey(30)&0xff
# Esc退出
if key == 27:
break
else:
break
# 關(guān)閉攝像頭
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
# 請(qǐng)輸入您的name和id
name = input('Please input your name:')
face_id = input('Please input face id:')
GetFace(name,face_id)
2.程序執(zhí)行效果
程序打印下列內(nèi)容,輸入人臉身份(如lyx),其次輸入身份ID(序號(hào)0,1,2…)。當(dāng)用戶輸入名字和ID,按下回車鍵后,只要用戶正對(duì)著攝像頭計(jì)算機(jī)會(huì)自動(dòng)采集人臉圖像,直到采集到100張有效照片后自動(dòng)退出,照片默認(rèn)保存在根目錄下的Facedata文件夾
六、 人臉模型訓(xùn)練實(shí)現(xiàn)
對(duì)采集到的人臉數(shù)據(jù)集進(jìn)行人臉特征提取并建立人臉模型,形成模型文件。
1.訓(xùn)練人臉模型FaceTrain.py代碼
import os
import cv2
from PIL import Image
import numpy as np
# 人臉訓(xùn)練集路徑
path = './Facedata/'
# 初始化識(shí)別器
# opencv-contrib-python和opencv-python庫(kù)版本要一致,否則運(yùn)行會(huì)報(bào)錯(cuò)
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 獲取分類器
detector = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')
# 獲取圖像及標(biāo)簽
def getImagesAndLabels(path):
# join函數(shù)的作用
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
faceSamples = []
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L')
img_numpy = np.array(PIL_img, 'uint8')
id = int(os.path.split(imagePath)[-1].split(".")[1])
faces = detector.detectMultiScale(img_numpy)
for (x, y, w, h) in faces:
faceSamples.append(img_numpy[y:y + h, x: x + w])
ids.append(id)
return faceSamples, ids
# 主程序入口
if __name__ == "__main__":
print('Training faces. It will take a few seconds. Waiting...')
faces, ids = getImagesAndLabels(path)
# 開始訓(xùn)練
recognizer.train(faces, np.array(ids))
print('Training has finished!')
# 保存文件
recognizer.write(r'./Model/trainer-2021.yml')
print("{0} faces trained. Exiting Program.".format(len(np.unique(ids))))
2.程序執(zhí)行效果
當(dāng)出現(xiàn)如下所示的信息時(shí),說明模型訓(xùn)練完成,模型文件默認(rèn)保存在當(dāng)前程序目錄下的Model文件夾
Training faces. It will take a few seconds. Waiting...
Training has finished!
1 faces trained. Exiting Program.
七、 人臉識(shí)別實(shí)現(xiàn)
通過攝像頭實(shí)時(shí)捕獲人臉圖像,進(jìn)行人臉追蹤,跟訓(xùn)練好的人臉模型trainer-20221230.yml進(jìn)行特征匹配,從而進(jìn)行人臉識(shí)別,對(duì)應(yīng)的用戶名字會(huì)實(shí)時(shí)顯示在人臉圖像上。
1.人臉識(shí)別FaceRecognition.py代碼
import os
import cv2
# 人臉識(shí)別函數(shù)
def Face():
# 獲取所有的模型文件路徑
model_dir = './Model/'
# 獲取分類器
faceCascade = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')
# 設(shè)置圖片顯示的字體
font = cv2.FONT_HERSHEY_SIMPLEX
# 用戶需要在此添加自己的姓名(拼音),下標(biāo)序號(hào)要與名字對(duì)應(yīng)(ID從0開始,依次遞增)
names = ['lyx', 'jk', 'xy']
# 捕獲圖像
camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 設(shè)置格式
minW = 0.1*camera.get(3)
minH = 0.1*camera.get(4)
# 初始化識(shí)別器
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 加載訓(xùn)練好的模型文件
print('請(qǐng)正對(duì)著攝像頭...')
confidence = 150.00
name = "unknown"
while True:
# 讀取圖片
success,img = camera.read()
# 圖片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 檢測(cè)人臉
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.3,
minNeighbors=5,
minSize=(int(minW), int(minH))
)
for (x, y, w, h) in faces:
# 畫一個(gè)矩形
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 遍歷指定目錄下的所有模型文件,能夠根據(jù)不同模型識(shí)別不同人,但是有些卡
for model_file in os.listdir(model_dir):
if not model_file.endswith('.yml'): #如果文件夾內(nèi)的文件格式不是.yml,就跳過
continue
# 初始化識(shí)別器
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read(r'./Model/'+ model_file)
# 圖像預(yù)測(cè) https://www.py.cn/jishu/jichu/26805.html
# predict()函數(shù)返回兩個(gè)元素的數(shù)組:第一個(gè)元素是所識(shí)別個(gè)體的標(biāo)簽,第二個(gè)是置信度評(píng)分。
# 置信度評(píng)分用來衡量所識(shí)別人臉與原模型的差距,0 表示完全匹配。
idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w])
print(confidence)
# 設(shè)置置信度confidence小于100%即可驗(yàn)證通過人臉
if confidence < 120:
name = names[idnum]
print("ID:",idnum,",name:",name)
break
else:
name = "unknown"
cv2.putText(img, str(name), (x+5, y-5), font, 1, (230, 250, 100), 1)
cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (255, 0, 0), 1)
cv2.imshow('camera', img)
# 保持畫面持續(xù)
key = cv2.waitKey(10)
# 按Esc鍵退出
if key==27 or confidence< 120:
cv2.imwrite('./Image.jpg', img) #保存圖片
break
# 關(guān)閉攝像頭
camera.release()
cv2.destroyAllWindows()
return name,idnum,confidence
if __name__ == '__main__':
# 加載訓(xùn)練好的模型文件
name,confidence = Face()
confidence = "{0}%".format(round(200 - confidence))
print("您的名字是:", name)
print("匹配指數(shù):", confidence)
2.關(guān)于置信度confidence
LBPH中置信度評(píng)分用來衡量所識(shí)別人臉與原模型的差距,0 表示完全匹配,predict()函數(shù)返回兩個(gè)元素的數(shù)組:第一個(gè)元素是所識(shí)別 個(gè)體的標(biāo)簽,第二個(gè)是置信度評(píng)分。其中由于本人采集人臉數(shù)據(jù)的干擾,confidence的值會(huì)在88-110以上(confidence想要接近0基本上概率為0),所以我設(shè)置了本項(xiàng)目score為200-confidence,反過來判斷score的值大于我設(shè)定的閾值(95)那么就判定為人臉識(shí)別成功。
3.程序執(zhí)行效果
在彈出圖像窗口并在人臉圖像上實(shí)時(shí)顯示用戶名和匹配指數(shù)。文章來源:http://www.zghlxwxcb.cn/news/detail-777615.html
程序鏈接
完成參考程序與第三方庫(kù):
鏈接:https://pan.baidu.com/s/1woGOnY8YWWfWSAQI6yldwg?pwd=lyx4
提取碼:lyx4文章來源地址http://www.zghlxwxcb.cn/news/detail-777615.html
到了這里,關(guān)于基于OpenCV提供的人臉識(shí)別算法LBPH實(shí)現(xiàn)人臉識(shí)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!