【人脸识别(二)】:如何使用 dlib 实现简单的人脸识别功能

您所在的位置:网站首页 人脸识别插件安装使用手册教程 【人脸识别(二)】:如何使用 dlib 实现简单的人脸识别功能

【人脸识别(二)】:如何使用 dlib 实现简单的人脸识别功能

2024-07-13 01:15| 来源: 网络整理| 查看: 265

人脸识别(一):Ubuntu Python安装dlib C++ library

人脸识别(三):使用face_recognition库实现人脸识别,python实现

人脸识别(四):人脸识别理论、原理、分类、概括,请针对性学习所需算法,不要全学。

人脸识别(五):基于Adaboost的人脸检测算法,及实例教程

目录

 

前言

检测人脸

检测视频的人脸

检测人脸的阈值设置

实现人脸识别/人脸对比

ROI追踪(感兴趣区域追踪)

图像中多张人脸识别

展望

针对本文的建议

  前言

dlib是不错的人脸检测、识别的库,检测精度为99.13%。

本文旨在教小白实现人脸检测、人脸识别、感兴趣区域追踪以及在视频中的应用。

本文涉及到的代码、图片、视频都已上传在本文资源中(也可以点击https://download.csdn.net/download/qq_39709813/12345196),供下载学习。受到时间关系的影响,本文没有过多的探索dlib库,希望读者可以在此基础上继续探索、开发。

务必安装requirem.txt文件中的必要库。

文档说明

face_images保存多张人多脸的图片,供学习使用

model保存已经下载好的模型数据

people_i_know保存已经认识的人的单张图片

unknow_people保存需要识别的人的图像

video保存检测和识别使用的视频

 

检测人脸

检测人脸,实现的是使用检测框将图像中的人脸检测出,使用的是dlib与PIL实现,保存在test1.py中。代码和检测结果如下:

import dlib from PIL import Image import numpy as py import os file_path = "./people_i_know/huge.jpg" detector = dlib.get_frontal_face_detector() # 加载检测器 win = dlib.image_window() image = py.array(Image.open(file_path)) # 读取图片 detector_face = detector(image, 1) # 检测 1是放大图片 win.clear_overlay() win.set_image(image) # 显示图pain win.add_overlay(detector_face) # 添加检测框 dlib.hit_enter_to_continue()

 

检测视频中的人脸

在检测人脸的基础上,融合opencv,实现视频中的人脸检测,保存在test2.py中,代码和结果如下:

import dlib import cv2 import numpy as np video_capture = cv2.VideoCapture("./video/hamilton_clip.mp4") # video_capture = cv2.VideoCapture(0) detector = dlib.get_frontal_face_detector() win = dlib.image_window() while video_capture.isOpened(): # Grab a single frame of video ret, frame = video_capture.read() # 逐帧读取图片 if not ret: break # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) frame = frame[:, :, ::-1] # BGR格式转成RGB格式 image = np.array(frame) detector_face = detector(image, 1) win.clear_overlay() win.set_image(image) win.add_overlay(detector_face) video_capture.release() cv2.destroyAllWindows()

 

检测人脸的阈值设置

以上检测人脸使用的都是默认的阈值,在实际练习的时候,可以按照自己的需求阈值。

可以简单的认为检测人脸时,都会有一个得分,当得分高于阈值时,将其输出。

dets, sco, idx = detector.run(image,0,1)为阈值设置部分,dets是检测框,sco是检测到的人脸得分,idx是检测器类型,1即为人为设定的阈值。

通过设置不同的阈值,你会发现检测框会很多,或者没有,或者吧人脸完美框住。

保存在test3.py中,代码和结果如下:

import numpy as py from PIL import Image path = "./people_i_know/huge.jpg" detector = dlib.get_frontal_face_detector() win = dlib.image_window() image = py.array(Image.open(path)) dets, sco, idx = detector.run(image,0,1) # 设置阈值 for i, d in enumerate(dets): print('%d:score %f, face_type %f' % (i, sco[i], idx[i])) win.clear_overlay() win.set_image(image) win.add_overlay(dets) dlib.hit_enter_to_continue()

 

 

实现人脸识别/人脸对比

识别人脸需要人脸特征向量,通过比对两张脸之间特征向量的距离来判定,需要检测的人是否认识,以及这个人叫什么。

因此,这里引入了shape_predictor_68_face_landmarks.dat与dlib_face_recognition_resnet_model_v1.dat,前者是人脸68点的检测模型,后者是人脸特征向量模型,都是已经训练好的。

这些模型数据都已经放在资源中,也可以自行去官网下载:http://dlib.net/files/

同时还引入了距离函数,代码中简化为 Eu(a,b)。具体代码保存在test4.py中,代码和结果如下:

import dlib from PIL import Image import numpy as np import os detector = dlib.get_frontal_face_detector() path_pre = "./model/shape_predictor_68_face_landmarks.dat" # 68点模型 pre = dlib.shape_predictor(path_pre) path_model = "./model/dlib_face_recognition_resnet_model_v1.dat" # resent模型 model = dlib.face_recognition_model_v1(path_model) path_know = "./people_i_know" # 已知人脸文件夹 path_unknow = "./unknow_people" # 需要检测的人来你文件夹 know_list = {} def Eu(a,b): # 距离函数 return np.linalg.norm(np.array(a) - np.array(b), ord=2) for path in os.listdir(path_know):# 载入已知人的名字和面部特征 img = np.array(Image.open(path_know+"/"+path)) name = path.split('.')[0] det_img = detector(img, 0) shape = pre(img, det_img[0]) know_encode = model.compute_face_descriptor(img, shape) know_list[name] = know_encode match = {} for path in os.listdir(path_unknow):#逐个载入待检测人的面部特征 img = np.array(Image.open(path_unknow+"/"+path)) name = path.split('.')[0] det_img = detector(img, 0) shape = pre(img, det_img[0]) unknow_encode = model.compute_face_descriptor(img, shape) match[name] = "unknow" for key, sco in know_list.items():# 与已知的面部特征匹配 if Eu(unknow_encode, sco) < 0.6: match[name] = key break for key, value in match.items(): print("picture:"+key+' is '+ value)

代码设计3个文件夹,

model文件夹存放的是上述的两个模型数据

people_i_know文件夹存放的是你事先知道的人,以及他的样子。

unknow_people文件夹存放的是你想识别的人,看这个人是否是你认识的(显示他的名字),或者是你不认识的(显示unknow)

从下图中可以看出,unknow2文件是obama,unknown3文件是biden,unknown4文件是不认识的人。

 

ROI追踪(感兴趣区域追踪)

感兴趣区域,是一副图像中,我们最关心的地方。感兴趣区域追踪,是指检测框将随着这个物体的移动而随之移动,始终将物体的位置检测出。

下列代码实现的是对视频中感兴趣区域的检测,代码一运行需要人为的使用鼠框选选自己感兴趣的区域,并按下enter确认,过后,检测框将自动追踪物体或者人。

保存在test5.py中,代码和结果如下:

import dlib import cv2 video_capture = cv2.VideoCapture("./video/hamilton_clip.mp4") # video_capture = cv2.VideoCapture(0) detector = dlib.correlation_tracker() win = dlib.image_window() i = 0 while video_capture.isOpened(): # Grab a single frame of video ret, frame = video_capture.read() if not ret: break # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) frame = frame[:, :, ::-1] if i == 0:#在第一帧的时候调用鼠标回去检测框的位置 cv2.namedWindow('image',flags=cv2.WINDOW_NORMAL) cv2.imshow('image',frame) rect = cv2.selectROI('image', frame, showCrosshair=False, fromCenter=False) cv2.destroyAllWindows() detector.start_track(frame, dlib.rectangle(rect[0],rect[1],rect[0]+rect[2],rect[1]+rect[3])) i=i+1 else:# 继续追踪内容 detector.update(frame) win.clear_overlay() win.set_image(frame) win.add_overlay(detector.get_position()) video_capture.release() cv2.destroyAllWindows()

下图蓝色框是人为使用鼠标框选的位置。

下图红色框是自动追踪的位置。由于视频中的摄像机经常切换位置,因此检测结果不是很理想。

可以知道:当场景的角度位置变化不大的时候,检测结果较理想;当场景切换过大,可能会出现误检测的现象。

 

图像中多张人脸识别

现实生活中,一张图往往有许多的人脸。下列代码重点就是将一幅图中认识的人脸识别出来,对不认识的人不检测。

检测使用的是dlib,绘图部分使用的是opencv。保存在test6.py中,代码和结果如下:

import dlib from PIL import Image import numpy as np import os import cv2 from imutils import face_utils detector = dlib.get_frontal_face_detector() path_pre = "./model/shape_predictor_68_face_landmarks.dat" pre = dlib.shape_predictor(path_pre) path_model = "./model/dlib_face_recognition_resnet_model_v1.dat" model = dlib.face_recognition_model_v1(path_model) path_know = "./people_i_know" path_unknow = "./face_images/bald_guys.jpg" know_list = {} def Eu(a,b): return np.linalg.norm(np.array(a) - np.array(b), ord=2) for path in os.listdir(path_know):# 建立已知人脸的字典库 img = np.array(Image.open(path_know+"/"+path)) name = path.split('.')[0] det_img = detector(img, 0) shape = pre(img, det_img[0]) know_encode = model.compute_face_descriptor(img, shape) know_list[name] = know_encode frame = cv2.imread(path_unknow) #frame = frame[:, :, ::-1] img = np.array(frame) det_img = detector(img, 0)#得到检测框 for rect in enumerate(det_img): shape = pre(img, rect[1]) (x,y,w,h) = face_utils.rect_to_bb(rect[1])#rect由tuple转成bb unknow_encode = model.compute_face_descriptor(img, shape) for key, sco in know_list.items(): if Eu(unknow_encode, sco) < 0.6: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 3)# 绘制检测框 cv2.putText(img, key, (x, y+h), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(255,0,0), 2)#绘制检测后的姓名 break cv2.namedWindow('image', cv2.WINDOW_NORMAL) cv2.imshow('output',img) cv2.waitKey(0)

检测的图像中包含许多张人脸,已经检测书的人:杰森斯坦森(joson)和强森(johnson)。从结果中,可以看到也有漏检测和检测错误的情况,原因在于,people_i_know文件夹下的joson和johnson是最新美化过的图像。

 

展望

目前,本文就实现这些功能,还有更多的功能可以实现,需要你自己慢慢探索。例如,结合opencv实现视频中多张人脸的识别和标注、提升机器运行速度等。

 

针对本文的建议

首先是按照要求安装必要的包;

其次是people_i_know文件夹里放置高清端正的图像;

所有的图片使用.jpg格式

 

下一篇将使用face_recognition库实现人脸检测、比对、识别以及拓展:

人脸识别(三):使用face_recognition库实现人脸识别,python实现



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3