【Dlib人脸识别】1. Dlib人脸检测的基本原理

【Dlib人脸识别】1. Dlib人脸检测的基本原理Dlib 中 人脸识别的基本思路为 计算已知图片中所有人脸对应的特征向量 计算要识别的未知图片中所有人脸对应的特征向量 计算人脸之间的欧式距离 如果两张人脸之间的欧式距离小于设定的阈值 则认为是同

大家好,欢迎来到IT知识分享网。

Dlib中,人脸识别的基本思路为:

  • 计算已知图片中所有人脸对应的特征向量;
  • 计算要识别的未知图片中所有人脸对应的特征向量;
  • 计算人脸之间的欧式距离;
  • 如果两张人脸之间的欧式距离小于设定的阈值,则认为是同一个人,否则认为不是同一个人

【 1. 计算特征向量 】

在人脸特征点检测中,我们学会了如何获取人脸的特征点。但是特征点只是用于标识人脸关键点的坐标而已,如果想要实现人脸识别,那么必须将特征点转换为特征向量。

1. 加载人脸识别模型

首先,我们得通过dlib.face_recognition_model_v1() 加载人脸识别的模型:

dlib.face_recognition_model_v1(人脸识别模型路径) 
import dlib import cv2 #人脸识别模型的路径 face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat' # 加载人脸识别模型 facerec = dlib.face_recognition_model_v1(face_rec_model_path) 

2. 计算特征向量

在加载完模型之后,我们需要先使用前面学到的知识,先检测特征点:

import cv2 # 加载人脸识别模型 face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat' facerec = dlib.face_recognition_model_v1(face_rec_model_path) # 加载特征点识别模型 predictor_path = "shape_predictor_5_face_landmarks.dat" predictor = dlib.shape_predictor(predictor_path) # 读取图片 img_path = "step1/image/face.jpg" img = cv2.imread(img_path) # 转换为灰阶图片 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 正向人脸检测器将图像 detector = dlib.get_frontal_face_detector() # 使用人脸识别模型来检测图像中的人脸 faces = detector(gray, 1) # 使用特征点识别模型来检测人脸中的特征 for i, face in enumerate(faces): # 获取人脸特征点 shape = predictor(img, face) 

通过上面的代码,我们检测到人脸的特征点,并将它们保存在shape中。下面我们通过facerec.compute_face_descriptor()来计算特征向量,它的函数声明如下:

facerec.compute_face_descriptor(图片对象, 特征点) 

具体代码如下:

face_descriptor = facerec.compute_face_descriptor(img,shape) 

这样,我们就计算出了人脸特征向量。

【 2. 计算欧氏距离 】

  • 欧氏距离(也称欧几里得距离)是一个常用的的距离度量,它指的是在空间中两个向量(点)之间的直线距离。
    欧氏距离越小,说明两个向量越接近,也就是两个向量差异越小。
  • 假设在两个向量分别为 x(x1,x2,…,xm) 和 y(y1,y2,…,ym),则这两个向量的欧氏距离的计算公式为:
    ( x 1 − y 1 ) 2 + ( x 2 − y 2 ) 2 + . . + ( x m − y m ) 2 ( x 1 − y 1 ) \sqrt{(x_1-y_1)^2+(x_2-y_2)^2+..+(x_m-y_m)^2}\sqrt{(x_1−y_1)} (x1y1)2+(x2y2)2+..+(xmym)2
    (x1y1)

  • Python中可以通过长度为 m 的列表来表示维数为 m 的向量。
    例如x为(1,2,3,4,5),那么它可以表示为x=[1,2,3,4,5]。
  • 在Python中计算两个长度相同的列表的欧氏距离:
import numpy as np # 导入numpy库 x = [1,2,3,4,5] # 声明两个长度相同的列表 y = [3,4,5,2,1] x_array = np.array(x) # 将列表转换为numpy数组 y_array = np.array(y) distance = np.linalg.norm(x_array-y_array) # 计算x_array与y_array之间的欧氏距离 

【 3. 识别人脸 】

1. 准备数据

2. 计算所有已知图片中人脸的特征向量

glob(正则表达式)# glob()返回匹配的文件列表, 

glob()会返回匹配的文件列表,这样我们就可以获取到在known_image_path下所有以jpg结尾的的图片,如下:

import glob glob.glob(os.path.join(known_image_path, "*.jpg")) 

然后我们就可以来计算所有已知图片中人脸的特征向量,代码如下所示:

known_image_path = "step1/image/known_image" # 声明descriptors,用于存放已知图片对应的人脸特征向量 descriptors = [] # 声明names,用于存放于人脸特征向量对应的名字。 names = ["TongDaWei","XiaYu","ZhangYiShan"] # 遍历known_image_path文件夹下所有以.jpg结尾的文件。 for f in glob.glob(os.path.join(known_image_path, "*.jpg")): img = dlib.load_rgb_image(f) # 1.人脸检测 dets = detector(img, 1) for k, d in enumerate(dets): # 2.关键点检测 shape = predictor(img, d) # 3.计算特征向量(也成为人脸描述符) descriptor = facerec.compute_face_descriptor(img, shape) # 转换为numpy数组 v = np.array(descriptor) descriptors.append(v) 

3. 识别人脸

当欧氏距离小于某个阈值时,则可以认为他们是同一个人。那这个阈值应该设定为多少呢?

  • 原理:计算待识别的图片特征向量与已知图片特征向量的欧氏距离,如果欧氏距离小于阈值,则认为是同一张图片。
  • 在Dlib中,对于在LFW人脸数据集,当阈值设置为0.6时,的识别精度能达到99.38%。
  • 但是,当阈值设置为0.6时,对于小孩和亚洲人的识别率不是很高。故我们要识别的图片是亚洲人时,要将阈值适当地降低,在这里我们设置为0.4。

具体代码片段如下

tolerance = 0.4 current_name = "Unknow" for i in range(len(descriptors)): #假设当前带识别的图片特征为current distance = np.linalg.norm(descriptors[i]-current) if distance<tolerance: #names用于存放于已知人脸特征向量对应的名字 current_name = names[i] break print("当前图片识别结果为:"+current_name) 

【 4. 范例 】

# 0. 导入模块 import os import dlib import glob import numpy as np import cv2 # 1. 加载模型、图片  正向人脸检测器 detector = dlib.get_frontal_face_detector()  加载特征点提取模型 predictor_path = 'shape_predictor_68_face_landmarks.dat' predictor = dlib.shape_predictor(predictor_path)  加载面部识别模型 face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat' facerec = dlib.face_recognition_model_v1(face_rec_model_path)  已知图片 known_image_path = 'know'  测试图片 test_image_path = "unknow" # 2. 声明存放数据的变量  声明descriptors,用于存放已知图片对应的人脸特征向量 descriptors = []  声明names,用于存放于人脸特征向量对应的名字。 names = ["reba"] # 3. 开始检测  遍历known_image_path文件夹下所有以.jpg结尾的文件。 for f in glob.glob(os.path.join(known_image_path, "*.jpg")): img = dlib.load_rgb_image(f)  使用 detector 检测器来检测图像中的人脸 dets = detector(img, 1) for k, d in enumerate(dets):  获取人脸特征点 shape = predictor(img, d)  计算特征向量 face_descriptor = facerec.compute_face_descriptor(img, shape)  特征向量转换为numpy array v = np.array(face_descriptor)  把此次数据存到人脸特征向量列表里面 descriptors.append(v) # 4. 进行判断  遍历test_image_path文件夹下所有以.jpg结尾的文件。 for f in glob.glob(os.path.join(test_image_path, "*.jpg")): img = dlib.load_rgb_image(f)  使用 detector 检测器来检测图像中的人脸 dets = detector(img, 1) for k, d in enumerate(dets):  获取人脸特征点 shape = predictor(img, d)  计算特征向量 face_descriptor = facerec.compute_face_descriptor(img, shape)  将当前待判断的图片特征向量转化为 current current = np.array(face_descriptor)  计算欧式距离,识别人脸  设置阈值 tolerance = 0.1  设置该图片名字初值为:Unknow current_name = "Unknow name"  对这个存放着已知图片特征向量的列表descriptors[]遍历 for i in range(len(descriptors)):  计算欧氏距离 distance = np.linalg.norm(descriptors[i] - current)  对欧氏距离判断 if distance < tolerance:  names用于存放着人脸特征向量对应的名字 current_name = names[i] break  输出对当前图片的识别结果 print("当前图片识别结果为:" + current_name) 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/134013.html

(0)
上一篇 2025-07-15 20:26
下一篇 2025-07-15 20:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信