最近在做人脸识别,就先拿简单的face_recognition练下手。face_recognition是基于dlib开发的一个开源人脸识别库,所以也可以直接用dlib开发人脸识别,不过相对来说麻烦一些,后期也会写篇文章详细说明。
本人使用的环境如下:
windows7
pycharm
python3.6.6
dlib19.7
face_recognition1.3.0
加粗python3.6的原因是它安装dlib比较方便,本人之前使用的是python3.7安装dlib时会出现cmake错误等等莫名其妙的的错误,使用python3.6以后一次成功,在此安利给大家。当然现在dlib的版本也已经很高了(19.19),但是由于怕出现问题就只安装了较低的版本,大家可以根据自己的情况自行调整,按照上面的来进行环境配置一般来说是不会出现问题的。
首先是要导入的模块,cv2就是opencv,用来调用摄像头以及进行一些处理。face_recognition用来实现人脸识别,os用来实现获取摄像头出现的人脸的名字。
import face_recognition
import cv2
import os
接下来是数据预处理。
camera = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_DUPLEX
face_names = []
face_codings = []
person_list = os.listdir("faces/")
for i in range(len(person_list)):
person_name = os.listdir("faces/" + "person_" + str(i + 1))
face_img = face_recognition.load_image_file("faces/" + "person_" + str(i + 1) + "/" + person_name[0])
face_codings.append(face_recognition.face_encodings(face_img)[0])
face_names.append(person_name[0][:person_name[0].index(".")])
这是我存放人脸的目录结构,默认图片的名字就是人名,可以更方便的获取人名。
接下来是人脸识别的主体代码,因为比较简单,就不放全部的了。
marks = face_recognition.face_locations(img_new)
codings = face_recognition.face_encodings(img_new, marks)
for coding in codings :
result= face_recognition.compare_faces(face_codings,coding,0.4)
print(result)
for i in range(len(result)):
if result[i]:
name = face_names[i]
break
if i == len(result)-1:
name = "someone"
marks是人脸在摄像头的一帧画面中的位置,可以使用marks在摄像头视频中圈出人脸,name则会显示在预处理中获取到的人名。人脸识别的核心函数是face_recognition.compare_faces,函数详细如下:
第一个参数是一个已有人脸编码的列表,第二个是需要对比的人脸编码,第三个是比较阈值默认为0.6。但是可以看到我用的是0.4,因为基于我的使用经验来看0.4要更好,看来网上的帖子有的说是因为中国人脸型和外国人不一样导致的,emmmm。返回值是一个列表由true和false构成,如下是我输出的返回值:
根据这个列表再用到数据预处理时得到的face_names以及opencv的相关函数就能实时的进行人脸识别啦。
完整代码附上:
# -*- coding: utf-8 -*-
import face_recognition
import cv2
import os
camera = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_DUPLEX
face_names = []
face_codings = []
person_list = os.listdir("faces/")
for i in range(len(person_list)):
person_name = os.listdir("faces/" + "person_" + str(i + 1))
# print(person_name[0])
face_img = face_recognition.load_image_file("faces/" + "person_" + str(i + 1) + "/" + person_name[0])
face_codings.append(face_recognition.face_encodings(face_img)[0])
face_names.append(person_name[0][:person_name[0].index(".")])
while True:
success,img=camera.read()
img_new = cv2.resize(img, (0, 0), fx=0.25, fy=0.25)
process_this_frame = True
if process_this_frame:
marks = face_recognition.face_locations(img_new)
codings = face_recognition.face_encodings(img_new, marks)
for coding in codings:
result = face_recognition.compare_faces(face_codings, coding,0.4)
print(result)
for i in range(len(result)):
if result[i]:
name = face_names[i]
break
if i == len(result)-1:
name = "unknown"
#break
process_this_frame = not process_this_frame
for (top, right, bottom, left)in (marks):
top *= 4
right *= 4
bottom *= 4
left *= 4
cv2.rectangle(img, (left, top), (right, bottom), (255, 0, 0), 2)
cv2.putText(img, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
cv2.imshow('face', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
camera.release()
cv2.destroyAllWindows()