使用python3.7和opencv4.1來實現人臉識別和人臉特徵比對以及模型訓練
OpenCV4。1已經發布將近一年了,其人臉識別速度和效能有了一定的提高,這裡我們使用opencv來做一個實時活體面部識別的demo
首先安裝一些依賴的庫
pip install opencv-python
pip install opencv-contrib-python
pip install numpy
pip install pillow
需要注意一點,最好將pip設定國內的阿里雲的源,否則安裝會很慢
win10在使用者目錄下建立一個pip資料夾,然後在pip資料夾內建立一個pip。ini檔案,檔案內容如下
[global]
trusted-host = mirrors。aliyun。com
index-url = http://mirrors。aliyun。com/pypi/simple
這樣就可以用國內的源來下載安裝包
一開始,我們可以簡單的在攝像頭中識別人的臉部和眼鏡,原來就是用opencv內建的分類器,對直播影像中的每一幀進行掃描
import numpy as np
import cv2
from settings import src
# 人臉識別
faceCascade = cv2。CascadeClassifier(src+‘haarcascade_frontalface_default。xml’)
# 識別眼睛
eyeCascade = cv2。CascadeClassifier(src+‘haarcascade_eye。xml’)
# 開啟攝像頭
cap = cv2。VideoCapture(0)
ok = True
result = []
while ok:
# 讀取攝像頭中的影象,ok為是否讀取成功的判斷引數
ok, img = cap。read()
# 轉換成灰度影象
gray = cv2。cvtColor(img, cv2。COLOR_BGR2GRAY)
# 人臉檢測
faces = faceCascade。detectMultiScale(
gray,
scaleFactor=1。2,
minNeighbors=5,
minSize=(32, 32)
)
# 在檢測人臉的基礎上檢測眼睛
for (x, y, w, h) in faces:
fac_gray = gray[y: (y+h), x: (x+w)]
result = []
eyes = eyeCascade。detectMultiScale(fac_gray, 1。3, 2)
# 眼睛座標的換算,將相對位置換成絕對位置
for (ex, ey, ew, eh) in eyes:
result。append((x+ex, y+ey, ew, eh))
# 畫矩形
for (x, y, w, h) in faces:
cv2。rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
for (ex, ey, ew, eh) in result:
cv2。rectangle(img, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
cv2。imshow(‘video’, img)
k = cv2。waitKey(1)
if k == 27: #按 ‘ESC’ to quit
break
cap。release()
cv2。destroyAllWindows()
第二步,就是為模型訓練收集訓練資料,還是透過攝像頭逐幀來收集,在指令碼執行過程中,會提示輸入使用者id,請從0開始輸入,即第一個人的臉的資料id為0,第二個人的臉的資料id為1,執行一次可收集一張人臉的資料
指令碼時間可能會比較長,會將攝像頭每一幀的資料進行儲存,儲存路徑在專案目錄下的Facedat目錄,1200個樣本後退出攝像錄製
import cv2
import os
# 呼叫筆記本內建攝像頭,所以引數為0,如果有其他的攝像頭可以調整引數為1,2
from settings import src
cap = cv2。VideoCapture(0)
face_detector = cv2。CascadeClassifier(src+‘haarcascade_frontalface_default。xml’)
face_id = input(‘n enter user id:’)
print(‘n Initializing face capture。 Look at the camera and wait 。。。’)
count = 0
while True:
# 從攝像頭讀取圖片
sucess, img = cap。read()
# 轉為灰度圖片
gray = cv2。cvtColor(img, cv2。COLOR_BGR2GRAY)
# 檢測人臉
faces = face_detector。detectMultiScale(gray, 1。3, 5)
for (x, y, w, h) in faces:
cv2。rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
count += 1
# 儲存影象
cv2。imwrite(“。/Facedata/User。” + str(face_id) + ‘。’ + str(count) + ‘。jpg’, gray[y: y + h, x: x + w])
cv2。imshow(‘image’, img)
# 保持畫面的持續。
k = cv2。waitKey(1)
if k == 27: # 透過esc鍵退出攝像
break
elif count >= 1200: # 得到1000個樣本後退出攝像
break
# 關閉攝像頭
cap。release()
cv2。destroyAllWindows()
第三步,對收集下來的人臉資料進行模型訓練,提取特徵,訓練後,會將特徵資料儲存在專案目錄中的face_trainer資料夾下面
import numpy as np
from PIL import Image
import os
import cv2
from settings import src
# 人臉資料路徑
path = ‘Facedata’
recognizer = cv2。face。LBPHFaceRecognizer_create()
detector = cv2。CascadeClassifier(src+“haarcascade_frontalface_default。xml”)
def getImagesAndLabels(path):
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’) # convert it to grayscale
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
print(‘訓練需要一定時間,請耐心等待。。。。’)
faces, ids = getImagesAndLabels(path)
recognizer。train(faces, np。array(ids))
recognizer。write(r‘。/face_trainer/trainer。yml’)
print(“{0} faces trained。 Exiting Program”。format(len(np。unique(ids))))
最後一步,人臉測試,我們將攝像頭中的人臉和模型中的特徵進行比對,用來判斷是否為本人
import cv2
from settings import src
recognizer = cv2。face。LBPHFaceRecognizer_create()
recognizer。read(‘。/face_trainer/trainer。yml’)
cascadePath = src+“haarcascade_frontalface_default。xml”
faceCascade = cv2。CascadeClassifier(cascadePath)
font = cv2。FONT_HERSHEY_SIMPLEX
idnum = 0
names = [‘andonghui’, ‘admin’]
cam = cv2。VideoCapture(0)
minW = 0。1*cam。get(3)
minH = 0。1*cam。get(4)
while True:
ret, img = cam。read()
gray = cv2。cvtColor(img, cv2。COLOR_BGR2GRAY)
faces = faceCascade。detectMultiScale(
gray,
scaleFactor=1。2,
minNeighbors=5,
minSize=(int(minW), int(minH))
)
for (x, y, w, h) in faces:
cv2。rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
idnum, confidence = recognizer。predict(gray[y:y+h, x:x+w])
if confidence < 100:
idnum = names[idnum]
confidence = “{0}%”。format(round(100 - confidence))
else:
idnum = “unknown”
confidence = “{0}%”。format(round(100 - confidence))
cv2。putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1)
cv2。putText(img, str(confidence), (x+5, y+h-5), font, 1, (0, 0, 0), 1)
cv2。imshow(‘camera’, img)
k = cv2。waitKey(10)
if k == 27:
break
cam。release()
cv2。destroyAllWindows()
整個流程並不複雜,可以讓opencv初學者感受一下人臉識別底層的邏輯,說明自研應用還是有一定可操作性的,並不是涉及機器學習的技術就動輒使用百度,阿里雲等三方支援。
最後,送上人臉識別專案地址:
https://
gitee。com/QiHanXiBei/fa
ce_get/tree/master