概況:
使用OpenCv,dlib人臉識别庫進行人臉實時識别
程式說明:
get_face.py:對人臉進行拍照,并将人臉圖檔儲存。
save_csv.py:讀取儲存的人臉圖檔,提取人臉的128D特征值存入csv檔案。
face_detect.py:打開攝像頭進行人臉的實時識别。
程式示例:
get_face.py
import cv2
# 打開攝像頭,0代表内置攝像頭,1代表外置攝像頭
camera = cv2.VideoCapture(0)
while True:
ret, frame = camera.read()
cv2.imshow('', frame)
# 按q鍵拍照儲存圖檔并退出
if cv2.waitKey(1) == ord('q'):
cv2.imwrite('人臉.png', frame)
break
# 釋放攝像頭資源
camera.release()
cv2.destroyAllWindows()
save_csv.py
import csv
import dlib
from skimage import io
import cv2
# Dlib 正向人臉檢測器
detector = dlib.get_frontal_face_detector()
# Dlib 人臉預測器
predictor = dlib.shape_predictor('data/data_dlib/shape_predictor_68_face_landmarks.dat')
# Dlib 人臉識别模型
facerec = dlib.face_recognition_model_v1('data/data_dlib/dlib_face_recognition_resnet_model_v1.dat')
# 傳回單張圖像的 128D 特征
def feature(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
faces = detector(img_gray, 1)
if len(faces) != 0:
shape = predictor(img_gray, faces[0])
descriptor = facerec.compute_face_descriptor(img_gray, shape)
else:
descriptor = 0
return descriptor
# 将照片特征提取出來, 寫入 CSV
def write_csv(face_path, csv_path):
image = io.imread(face_path)
feature_128d = feature(image)
with open('data.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(feature_128d)
if __name__ == '__main__':
write_csv('人臉.png', 'data.csv')
face_detect.py
import cv2
import dlib
import pandas as pd
import numpy as np
# Dlib 正向人臉檢測器
detector = dlib.get_frontal_face_detector()
# Dlib 人臉預測器
predictor = dlib.shape_predictor('data/data_dlib/shape_predictor_68_face_landmarks.dat')
# Dlib 人臉識别模型
facerec = dlib.face_recognition_model_v1('data/data_dlib/dlib_face_recognition_resnet_model_v1.dat')
# 計算兩個128D向量間的歐式距離
def distance(feature_1, feature_2):
feature_1 = np.array(feature_1)
feature_2 = np.array(feature_2)
dist = np.linalg.norm(feature_1 - feature_2)
if dist > 0.4:
return False
else:
return True
# 處理存放所有人臉特征的 csv
csv_rd = pd.read_csv('data.csv', header=None)
# 用來存放所有錄入人臉特征的數組
known_arr = []
# 讀取已知人臉資料
for i in range(csv_rd.shape[0]):
someone_arr = []
for j in range(0, len(csv_rd.ix[i, :])):
someone_arr.append(csv_rd.ix[i, :][j])
known_arr.append(someone_arr)
camera = cv2.VideoCapture(0)
while True:
ret, frame = camera.read()
# 取灰階
img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 人臉數 faces
faces = detector(img_gray, 0)
# 存儲目前攝像頭中捕獲到的所有人臉的名字
namelist = []
# 按下 q 鍵退出
if cv2.waitKey(1) == ord('q'):
break
else:
# 檢測到人臉
if len(faces) != 0:
feature_arr = []
# 擷取目前捕獲到的圖像的所有人臉的特征,存儲到 feature_arr
for i in range(len(faces)):
shape = predictor(img_gray, faces[i])
feature_arr.append(facerec.compute_face_descriptor(img_gray, shape))
# 周遊捕獲到的圖像中所有的人臉
for k in range(len(faces)):
# 先預設所有人不認識,是 unknown
namelist.append('unknown')
# 對于某張人臉,周遊所有存儲的人臉特征
for i in range(len(known_arr)):
# 将某張人臉與存儲的所有人臉資料進行比對
compare = distance(feature_arr[k], known_arr[i])
# 找到了相似臉
if compare == True:
if i == 0:
namelist[k] = 'wei'
# 繪制矩形框
for kk, d in enumerate(faces):
cv2.rectangle(frame, (d.left(), d.top()), (d.right(), d.bottom()), (0, 255, 0), 2)
# 在人臉框下面寫人臉名字
for i in range(len(faces)):
cv2.putText(frame, namelist[i], (faces[i].left(), faces[i].top()), 0, 1.5, (0, 255, 0), 2)
cv2.imshow('', frame)
# 釋放攝像頭
camera.release()
# 删除建立的視窗
cv2.destroyAllWindows()