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 | # 结果打上标签 |