Face Recognition
前面的
Dlib库,它是一个在工业界和学术界广受好评,极其优秀的库。而Face Recognition基于Dlib库做了高度封装,当之无愧的称之为世界上最简洁的人脸识别库。学习完基础的原理以及
Dlib库,就好比学会了“走路”;而Face Recognition库的高效与简洁,可以彻底“跑起来”。
一、人脸检测
1. 读取照片
在face rcognition中使用 load_image_file 函数读取图片:
1 | load_image_file(file, mode='RGB') |
其中,各个参数的含义如下:
file:带检测的图片文件路径;mode:可选值,默认为RGB,也可以指定为L,代表转化为灰度照片。
1 | # eg |
2. 检测照片中人脸并返回人脸位置
使用face_locations函数检测人脸:
1 | face_locations(img, number_of_times_to_upsample=1, model="hog") |
其中,各个参数的含义如下:
img:待检测的图片对象;number_of_times_to_upsample:可选值,为寻找人脸进行多少次图片变换,值越大,越能找到更小的人脸;model:可选值,默认使用hog模式,hog模式在CPU上运行表现更好;如果有GPU加速,也可以指定为cnn模式。
1 | # eg |
完整示例
1 | # 加载face_recognition库 |
3. 绘制人脸区域
使用OPenCV绘制人脸区域:
1 | import cv2 |
二、人脸特征点获取
1. 读取照片
方法同一.1
2. 获取照片中人脸特征点
可以使用face_landmarks函数,获取人脸中特征点:
1 | face_landmarks(face_image, face_locations=None, model="large") |
其中,各个参数含义如下:
face_image:图片对象;face_locations:可选,默认为空,也可以指定要识别的人脸区域位置;model:可选,不指定时的默认值为large,另一个值为small。large代表识别68个特征点,small代表识别5个特征点。
1 | # eg |
完整代码示例:
1 | # 导入face_recognition库 |

上面运行的结果对于图片里的一个人都有很多特征值。可以看出,返回的结果是一个一位数组,数组的元素为 JSON 格式,包含的特征区域细分为:
- 脸颊
chin; - 左眼眉毛
left_eyebrow; - 右眼眉毛
right_eyebrow; - 鼻梁
nose_bridge; - 鼻尖
nose_tip; - 左眼
left_eye; - 右眼
right_eye; - 上嘴唇
top_lip; - 下嘴唇
bottom_lip。
如果指定为 small 模式:
1 | face_landmarks_list = face_recognition.face_landmarks(image, model='small') |
3. 绘制特征点
依然是用到OpenCV,在前面获取到人脸特征点的基础代码上,加上下面的绘制代码:
1 | for face_landmarks in face_landmarks_list: |
结果:
三、人脸识别
1. 读取图片
与之前不同,因为是识别图片,所以我们需要分别读取已知名字图片和未知名字图片:
1 | known_image = face_recognition.load_image_file("./step3/images/cyx2.jpg") |
2. 获取128维的特征向量
可以使用 face_encodings 函数对人脸进行编码,获取到对应128维的人脸特征向量:
1 | face_encodings(face_image, known_face_locations=None, num_jitters=1) |
其中,各个参数的含义如下:
face_image:包含单个或者多个人脸的图片对象;known_face_locations:可选值,已经知道名字的人脸位置;num_jitters:当计算编码时,进行多少次的re-sample操作,次数越多,越精准(但同时会更慢,例如,值为100时,会慢100倍)。
分别对已知名字的人脸和未知名字的人脸,进行编码,示例代码如下:
1 | cyx_encoding = face_recognition.face_encodings(known_image)[0] |
3. 比较特征向量,识别人脸
最后,使用 compare_faces函数,比较已经人脸与未知人脸之间特征向量:
1 | compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6) |
其中,各个参数的含义如下:
known_face_encodings:已知人脸特征向量的数组;face_encoding_to_check:一个用于与已知向量相比较的未知人脸特征向量;tolerance:容错率,默认的容错率是0.6,容错率越低,识别越严格准确。
如果未知图片高于指定的容错率阈值,将会返回真(True);如果低于指定的阈值,将会返回假(False)。
1 | results = face_recognition.compare_faces([cyz_encoding], unknown_encoding, tolerance=0.4) |
完整示例:
1 | import face_recognition |
运行结果为[True],人脸识别结果正确。
四、人脸识别绘制并展示
1. 导入已知图片
同样是使用face rcognition中的 load_image_file 函数读取图片:
1 | known_image_cc = face_recognition.load_image_file("./step3/know_image/Caocao.jpg") |
2. 编码已知图片
使用face_encodings对图片进行编码,获取128维特征向量。之后需要遍历已知照片来识别,所以将人脸的特征向量存为数组。
1 | # 对图片进行编码,获取128维特征向量 |
3. 导入未知图片
准备好已知图片信息,加载将要识别的未知图片:
1 | # 加载待识别图片 |
4. 遍历识别
遍历未知图片,对每一种未知图片,获取其人脸位置和特征向量。将得到的位置图片特征向量与所有已知的特征向量进行比较,判断是否为同一个人。需要注意的是这里我们设置 tolerance 为0.5,实际应用时,可以根据自己对准确度的要求,进行调整。
1 | # 初始化一些变量 |
得到是否是同一个人的结果之后,我们可以对应其姓名,添加到face_names数组中:
1 | name = None |
5. 绘制姓名和人脸
得到对应的人脸识别结果之后,我们将遍历每一张未知图片中的人脸,通过 OpenCV的rectangle绘制脸部区域框和putText对应的人名:
1 | # 结果打上标签 |