您當前的位置:首頁 > 攝影

使用python3.7和opencv4.1來實現人臉識別和人臉特徵比對以及模型訓練

作者:由 劉悅的技術部落格 發表于 攝影時間:2020-04-08

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

標簽: cv2  img  faces  gray  face