首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python 利用 Dlib 实现摄像头实时人脸识别

0. 引言

利用 Python 语言开发,借助 Dlib 库提取出摄像头视频流中的人脸,提取人脸特征并计算特征值之间的欧氏距离,来和预存的人脸特征进行对比,判断是否匹配,达到人脸识别的目的;

实现的效果:

图1 已知人脸

图 2 未知人脸

图 3 多个已知人脸

1. 设计流程

先说下 人脸检测 ( Face Detection ) 和 人脸识别 ( Face Recognition ) ,人脸检测是达到检测出场景中人脸的目的就可以了,而后者不仅需要检测出人脸,还要和 已有人脸数据进行比对,识别出是否在数据库中,或者进行身份标注之类处理,人脸检测 和 人脸识别 两者有时候可能会被理解混淆;

Wikipedia 关于人脸识别系统 / Face Recognition System 的描述比较形象:they work by comparing selected facial features from given image with faces within a database.

本项目参考自 Dlib 官网例程 :

#face recognition model, the object maps human faces into 128D vectors

facerec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat"

shape =predictor(img, dets[0])

face_descriptor = facerec.compute_face_descriptor(img, shape)

项目核心在于 利用 “dlib_face_recognition_resnet_model_v1.dat” 这个 model,提取人脸图像的 128D 特征 "face_descriptor",然后比对不同人脸图片的 128D 特征,计算不同人脸的 128D 特征的欧氏距离 来判断是否为同一张脸;

大概流程如下:

人脸录入 >>> 存入本地 CSV >>>

调用摄像头实时获取视频流 >>>

Dlib 实时人脸检测并计算 128D 特征 >>>

将摄像头人脸的特征与已知人脸特征进行比对 >>>

如果有欧式距离比较小的认为有相似的人脸显示人名

图 4 设计流程

2. 源码介绍

主要有

get_face_from_camera.py ,

get_features_into_CSV.py ,

face_reco_from_camera.py

这三个 python 文件,下面分别介绍;

2.1 get_face_from_camera.py / 人脸注册录入

人脸识别需要将 提取到的图像数据 和 已有图像数据 进行比对分析,所以这部分代码实现的功能就是 人脸录入;

程序会生成一个窗口,显示调用的摄像头实时获取的图像;

然后根据键盘输入进行人脸捕获:

> “N” 新录入人脸,新建文件夹 person_X/ 用来存储某人的人脸图像

> "S" 开始捕获人脸,将捕获到的人脸放到 person_X/ 路径下

> “Q” 退出窗口

部分代码:

#利用 Dlib 的正向人脸检测器

detector =dlib.get_frontal_face_detector()

rects =detector(img_gray, 0)

#遍历每个检测到的人脸

for k, d in enumerate(rects):

#计算坐标

pos_start =tuple([d.left(), d.top()])

pos_end =tuple([d.right(), d.bottom()])

#计算高度

height = d.bottom() -d.top()

width = d.right() -d.left()

#画人脸矩形特征框

cv2.rectangle(im_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255), 2)

#根据人脸大小生成空的图像

im_blank = np.zeros((height, width, 3), np.uint8)

#按下 s 存储图片

ifkk == ord('s'):

cv2.imwrite("xxx.jpg", im_blank)

图 5 人脸矩形框坐标介绍

这样我们得到了 person_1, person_2, person_3... 的人脸图片,如下图所示。

图 6 存储的 person_x 的一组人脸

2.2 get_features_into_CSV.py /将图像文件中人脸数据提取出来存入CSV

这部分代码实现的功能是将之前捕获到的人脸图像文件,提取出 128D 特征,然后计算出某人人脸数据的特征均值存入 CSV 中,方便之后识别时候进行比对;利用 numpy.mean() 计算特征均值;

get_features_into_CSV.py 的部分代码:

# return_128d_features() 获取某张图像的 128D 特征

shape =predictor(img_gray, dets[0])

face_descriptor =facerec.compute_face_descriptor(img_gray, shape)

# write_into_csv() 将某个文件夹中的图像读取特征并写入 CSV

with open ("xx_csv","w", newline="") as csvfile:

writer = csv.writer(csvfile)

features_128d = return_128d_features(img_xxx)

writer.writerow(features_128d)

# compute_the_mean() 从 CSV 中读取 128D 特征,并计算特征均值

np.mean 计算均值

2.3 face_reco_from_camera.py/ 实时人脸识别对比分析

这部分源码实现的功能:

调用摄像头,捕获摄像头中的人脸,然后如果检测到人脸,将摄像头中的人脸提取出 128D 的特征,然后和之前录入人脸的 128D 特征 进行计算欧式距离,如果比较小(小于一个设定的阈值),可以判定为一个人,否则不是一个人;

欧氏距离对比的阈值设定,是在 return_euclidean_distance 函数的 dist 变量;

这部分实现的流程如下:

调用摄像头实时获取视频流 >>>

Dlib 实时人脸检测并计算 128D 特征 >>>

将摄像头人脸的特征与已知人脸特征进行比对 >>>

如果有欧式距离比较小的认为有相似的人脸显示人名

部分代码如下:

# 当摄像头开启时

whilecap.isOpened():

# 读取视频流

flag, img_rd =cap.read()

img_gray =cv2.cvtColor(img_rd, cv2.COLOR_RGB2GRAY)

#存储所有人脸的坐标/名字

pos_namelist =[]

name_namelist =[]

#遍历捕获到的图像中所有的人脸

forkinrange(len(faces)):

#让人名跟随在矩形框的下方

#确定人名的位置坐标

#先默认所有人不认识,是 unknown

name_namelist.append("unknown")

#每个捕获人脸的名字坐标

pos_namelist.append(tuple([faces[k].left(), int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)]))

#对于某张人脸,遍历所有存储的人脸特征

foriinrange(len(features_known_arr)):

print("with person_", str(i+1),"the", end='')

#将某张人脸与存储的所有人脸数据进行比对

compare =return_euclidean_distance(features_cap_arr[k], features_known_arr[i])

ifcompare =="same":#找到了相似脸

name_namelist[k] ="person_"+ str(i+1)

#矩形框

forkk, dinenumerate(faces):

#绘制矩形框

cv2.rectangle(img_rd, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]), (0, 255, 255), 2)

#写人脸名字

foriinrange(len(faces)):

cv2.putText(img_rd, name_namelist[i], pos_namelist[i], font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)

print("Name list now:", name_namelist,"\n")

cv2.putText(img_rd,"Face Register", (20, 40), font, 1, (255, 255, 255), 1, cv2.LINE_AA)

cv2.putText(img_rd,"Faces:"+ str(len(faces)), (20, 100), font, 1, (0, 0, 255), 1, cv2.LINE_AA)

cv2.imshow("camera", img_rd)

#释放摄像头

cap.release()

#删除建立的窗口

cv2.destroyAllWindows()

# 代码已上传到了我的 GitHub,如果对您有帮助欢迎 Star 下:https://github.com/coneypo/Dlib_face_recognition_from_camera

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180908G1JIF100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券