「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」
使用 dlib 进行人脸检测
基于 HOG 特征和滑动窗口的人脸检测器
在 dlib 中提供了基于方向梯度直方图 (Histogram of Oriented Gradients, HOG) 特征和滑动窗口检测方法中的线性分类器,使用基于结构 SVM 的训练算法用于人脸检测,分类器能够在每个训练图像的所有子窗口中进行训练,此人脸检测器使用来自户外标记人脸 (Labeled Faces in the Wild, LFW) 数据集的 3,000 张图像进行了训练。
如需使用 dlib 中的基于 HOG 特征和滑动窗口的人脸检测器检测人脸,第一步是从 dlib 加载人脸检测器:
# 加载人脸检测器
# 第二种方法的第一行代码
detector = dlib.get_frontal_face_detector()
# 加载图像并转换为灰度图像
img = cv2.imread('example.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
下一步是执行检测:
# 执行检测
# 第二种方法的第二行代码,至此第二种方法也讲解完毕了
rects_1 = detector(gray, 0)
rects_2 = detector(gray, 1)
detector() 的第二个参数表示在执行检测过程之前对图像进行上采样的次数,因为图像越大检测器检测到更多的人脸的可能性就越高,但执行时间相应也会增加。
最后可视化检测结果:
def show_detection(image, faces):
for face in faces:
cv2.rectangle(image, (face.left(), face.top()), (face.right(), face.bottom()), (255, 255, 0), 5)
return image
# 绘制检测框
img_faces_2 = show_detection(img.copy(), rects_2)
img_faces_2 = show_detection(img.copy(), rects_2)
# 绘制图像
show_img_with_matplotlib(img_faces_1, "detector(gray, 0): " + str(len(rects_1)), 1)
show_img_with_matplotlib(img_faces_2, "detector(gray, 1): " + str(len(rects_2)), 2)
plt.show()
如上图所示,如果使用原始灰度图像 (rects_1 = detection(gray, 0)) 检测人脸,则只能找到三张人脸。但是,如果我们使用上采样 1 次的灰度图像 (rects_2 = detection(gray, 1)) 检测人脸,则可以正确的检测到四个人脸。
值得注意的是,该检测器同样也可以用于发现人脸以外的目标。可以通过查看 dlib 库中的 train_object_detector.py 源码,了解如何仅使用少量训练图像训练自定义对象检测器。例如,可以仅使用十张交通标志图像来训练出色的交通标志检测器。
基于 CNN 的人脸检测器
dlib 库同样也提供了 CNN 人脸检测器,可以使用 dlib.cnn_face_detection_model_v1() 创建 CNN 人脸检测器。 dlib.cnn_face_detection_model_v1() 函数从传入的文件加载人脸检测模型,因此首先下载预训练模型。创建 CNN 人脸检测器时,将下载完成的预训练模型传递给此方法:
cnn_face_detector = dlib.cnn_face_detection_model_v1("mmod_human_face_detector.dat")
之后,我们使用此检测器来检测人脸:
rects = cnn_face_detector(img, 0)
检测器返回 mmod_rectangles 对象,它是一个 mmod_rectangle 对象的列表,并且 mmod_rectangle 对象有两个成员变量—— dlib.rectangle 对象和预测的置信度分数,为了显示检测结果,编写 show_detection() 函数:
def show_detection(image, faces):
"""使用矩形检测框显式标示每个检测到的人脸"""
for face in faces:
cv2.rectangle(image, (face.rect.left(), face.rect.top()), (face.rect.right(), face.rect.bottom()), (255, 255, 0), 5)
return image
# 绘制检测框
img_faces = show_detection(img.copy(), rects)
# 可视化
show_img_with_matplotlib(img_faces, "cnn_face_detector(img, 0): " + str(len(rects)), 1)
plt.show()
dlib-CNN 人脸检测器比 dlib-HOG 人脸检测器准确得多,但需要更多的算力来运行。例如,对于 600 x 400 的图像,HOG 人脸检测器需要大约 0.25 秒,而 CNN 人脸检测器却需要大约 5 秒。因此,为了加快 CNN 人脸检测器的执行速度,则可以通过在含有 GPU 的计算机上启用 CUDA 以达到合理的速度,但是需要从源码编译安装 dlib。