目录
- 一、采集人脸图片
-
- 1. Dlib库简介
- 2. OpenCV简介
- 3.代码实现
- 二、采集对应的68个特征点数组
-
- 三、实现人脸识别
-
- 总结
一、采集人脸图片
1. Dlib库简介
- Dlib库是一个机器学习的开源库,包含了机器学习的很多算法,使用起来很方便,直接包含头文件即可,并且不依赖于其他库(自带图像编解码库源码)。Dlib可以帮助创建很多复杂的机器学习方面的软件来帮助解决实际问题。目前Dlib已经被广泛的用在行业和学术领域,包括机器人,嵌入式设备,移动电话和大型高性能计算环境。
- 基于dlib库对人脸特征进行提取,在视频流中抓取人脸特征、并保存为64x64大小的图片文件。注意的是:因为我们后面会对人脸数据集进行训练识别,因此,这一步非常重要
2. OpenCV简介
- OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
3.代码实现
import cv2
import dlib
import os
import sys
import random
output_dir = 'D:/Myworkspace/JupyterNotebook/People/person/person2'
size = 64
if not os.path.exists(output_dir):
os.makedirs(output_dir)
def relight(img, light=1, bias=0):
w = img.shape[1]
h = img.shape[0]
for i in range(0,w):
for j in range(0,h):
for c in range(3):
tmp = int(img[j,i,c]*light + bias)
if tmp > 255:
tmp = 255
elif tmp < 0:
tmp = 0
img[j,i,c] = tmp
return img
detector = dlib.get_frontal_face_detector()
camera = cv2.VideoCapture(0)
index = 1
while True:
if (index <= 20):
print('Being processed picture %s' % index)
success, img = camera.read()
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dets = detector(gray_img, 1)
for i, d in enumerate(dets):
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img[x1:y1,x2:y2]
face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
face = cv2.resize(face, (size,size))
cv2.imshow('image', face)
cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
index += 1
key = cv2.waitKey(30) & 0xff
if key == 27:
break
else:
print('Finished!')
camera.release()
cv2.destroyAllWindows()
break
- 采集的照片位于person1文件夹中
二、采集对应的68个特征点数组
- 采集人脸68个特征数组需要导入
shape_predictor_68_face_landmarks.dat
Dlib人脸检测器,同时也要导入Dlib 人脸识别模型dlib_face_recognition_resnet_model_v1.dat
然后将特征数组存入csv文件中供人脸识别使用。
代码实现
from cv2 import cv2 as cv2
import os
import dlib
from skimage import io
import csv
import numpy as np
path_images_from_camera = "D:/Myworkspace/JupyterNotebook/People/person/"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("D:/shape_predictor_68_face_landmarks.dat")
face_rec = dlib.face_recognition_model_v1("D:/Myworkspace/dlib_face_recognition_resnet_model_v1.dat")
def return_128d_features(path_img):
img_rd = io.imread(path_img)
img_gray = cv2.cvtColor(img_rd, cv2.COLOR_BGR2RGB)
faces = detector(img_gray, 1)
print("%-40s %-20s" % ("检测到人脸的图像 / image with faces detected:", path_img), '\n')
if len(faces) != 0:
shape = predictor(img_gray, faces[0])
face_descriptor = face_rec.compute_face_descriptor(img_gray, shape)
else:
face_descriptor = 0
print("no face")
return face_descriptor
def return_features_mean_personX(path_faces_personX):
features_list_personX = []
photos_list = os.listdir(path_faces_personX)
if photos_list:
for i in range(len(photos_list)):
print("%-40s %-20s" % ("正在读的人脸图像 / image to read:", path_faces_personX + "/" + photos_list[i]))
features_128d = return_128d_features(path_faces_personX + "/" + photos_list[i])
if features_128d == 0:
i += 1
else:
features_list_personX.append(features_128d)
else:
print("文件夹内图像文件为空 / Warning: No images in " + path_faces_personX + '/', '\n')
if features_list_personX:
features_mean_personX = np.array(features_list_personX).mean(axis=0)
else:
features_mean_personX = '0'
return features_mean_personX
people = os.listdir(path_images_from_camera)
people.sort()
with open("D:/Myworkspace/features3_all.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
for person in people:
print("##### " + person + " #####")
features_mean_personX = return_features_mean_personX(path_images_from_camera + person)
writer.writerow(features_mean_personX)
print("特征均值 / The mean of features:", list(features_mean_personX))
print('\n')
print("所有录入人脸数据存入 / Save all the features of faces registered into: D:/myworkspace/features_all3.csv")
- 特征数据
三、实现人脸识别
- 通过对pc端摄像头的调用对出现的人脸进行计算欧氏距离并与=与已经存在的对象的数据进行比对。
代码
import os
import winsound
from playsound import playsound
import dlib
import csv
import time
import sys
import numpy as np
from cv2 import cv2 as cv2
import pandas as pd
facerec = dlib.face_recognition_model_v1("D:/Myworkspace/dlib_face_recognition_resnet_model_v1.dat")
def return_euclidean_distance(feature_1, feature_2):
feature_1 = np.array(feature_1)
feature_2 = np.array(feature_2)
dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
return dist
path_features_known_csv = "D:/Myworkspace/features2_all.csv"
csv_rd = pd.read_csv(path_features_known_csv, header=None)
features_known_arr = []
for i in range(csv_rd.shape[0]):
features_someone_arr = []
for j in range(0, len(csv_rd.iloc[i, :])):
features_someone_arr.append(csv_rd.iloc[i, :][j])
features_known_arr.append(features_someone_arr)
print("Faces in Database:", len(features_known_arr))
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('D:/shape_predictor_68_face_landmarks.dat')
cap = cv2.VideoCapture(0)
cap.set(3, 480)
while cap.isOpened():
flag, img_rd = cap.read()
kk = cv2.waitKey(1)
img_gray = cv2.cvtColor(img_rd, cv2.COLOR_RGB2GRAY)
faces = detector(img_gray, 0)
font = cv2.FONT_HERSHEY_COMPLEX
pos_namelist = []
name_namelist = []
if kk == ord('q'):
break
else:
if len(faces) != 0:
features_cap_arr = []
for i in range(len(faces)):
shape = predictor(img_rd, faces[i])
features_cap_arr.append(facerec.compute_face_descriptor(img_rd, shape))
for k in range(len(faces)):
print("##### camera person", k+1, "#####")
name_namelist.append("unknown")
pos_namelist.append(tuple([faces[k].left(), int(faces[k].bottom() + (faces[k].bottom() - faces[k].top())/4)]))
e_distance_list = []
for i in range(len(features_known_arr)):
if str(features_known_arr[i][0]) != '0.0':
print("with person", str(i + 1), "the e distance: ", end='')
e_distance_tmp = return_euclidean_distance(features_cap_arr[k], features_known_arr[i])
print(e_distance_tmp)
e_distance_list.append(e_distance_tmp)
else:
e_distance_list.append(999999999)
similar_person_num = e_distance_list.index(min(e_distance_list))
print("Minimum e distance with person", int(similar_person_num)+1)
if min(e_distance_list) < 0.4:
folder_name = 'D:/Myworkspace/JupyterNotebook/People/person'
sum=similar_person_num+1
key_id=1
file_names = os.listdir(folder_name)
for name in file_names:
if sum ==key_id:
name_namelist[k] = name[0:]
key_id += 1
for i, d in enumerate(faces):
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img_rd[x1:y1,x2:y2]
size = 64
face = cv2.resize(face, (size,size))
path_visitors_save_dir = "D:/Myworkspace/JupyterNotebook/People/known"
now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
save_name = str(now_time)+str(name_namelist[k])+'.jpg'
save_path = path_visitors_save_dir+'/'+ save_name
visitor_names = os.listdir(path_visitors_save_dir)
visitor_name=''
for name in visitor_names:
visitor_name=(name[0:16]+'-00'+name[19:])
visitor_save=(save_name[0:16]+'-00'+save_name[19:])
if visitor_save!=visitor_name:
cv2.imwrite(save_path, face)
print('新存储:'+path_visitors_save_dir+'/'+str(now_time)+str(name_namelist[k])+'.jpg')
else:
print('重复,未保存!')
else:
print("Unknown person")
for i, d in enumerate(faces):
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img_rd[x1:y1,x2:y2]
size = 64
face = cv2.resize(face, (size,size))
path_visitors_save_dir = "D:/Myworkspace/JupyterNotebook/People/unknown"
now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
save_path = path_visitors_save_dir+'/'+ str(now_time)+'unknown.jpg'
cv2.imwrite(save_path, face)
print('新存储:'+path_visitors_save_dir+'/'+str(now_time)+'unknown.jpg')
for kk, d in enumerate(faces):
cv2.rectangle(img_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255), 2)
print('\n')
for i in range(len(faces)):
cv2.putText(img_rd, name_namelist[i], pos_namelist[i], font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)
print("Faces in camera now:", name_namelist, "\n")
cv2.putText(img_rd, "Face Recognition", (20, 40), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
cv2.putText(img_rd, "Visitors: " + str(len(faces)), (20, 100), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
cv2.imshow("camera", img_rd)
cap.release()
cv2.destroyAllWindows()
人脸识别测试
- 对本人录入的照片数据记为person1,准确识别!
- 在网上随机找到的人脸图片,结果为unknown。
总结
- 通过使用dlib现有的人脸识别库和OpenCV可以很方便地实现对个体的人脸识别,同时计算不同的个体的面部特征值来区分不同人的区别极大简化了人脸识别的难度。