陈张杰
南方科技大学计算机科学与工程系三年级

人脸检测技术是指对于任意一幅给定的图像,通过计算机算法对其进行搜索以确定其中是否含有人脸,如果其中包含人脸则标定人脸的位置、大小等特征。这项技术近年来非常火热,而这项技术的普及也带来了对于检测率、效率等各方面的需求,这些需求也影响了人们对于模型的选择。
基于Haar特征的级联分类器(Haar Feature-based Cascade Classifier)于2001年被提出,这是一种经典的人脸检测算法,通过Haar特征有效地检测对象,通过积分图来提高图像特征值计算的效率,通过AdaBoost算法来训练一个强分类器。一直以来这项技术凭借着快速、出色的检测效果在人脸检测方面获得了广泛的应用。
基于卷积神经网络的YuNet于2018年12月发布,2019年3月开源。它是一个强大的、轻量级的人脸检测模型,可以装载在大部分设备上运行。YuNet的人脸检测速度可达到1000fps,并且可以检测很多较难检测的对象,如被遮挡的人脸、侧脸等。
当技术使用者需要一个模型来进行人脸检测时,到底是继续沿用传统分类器模型,还是改用基于神经网络的新方法,成为了一个令人纠结的问题。很多人会认为传统方法训练简单,消耗的计算力更少,检测人脸速度更快,效率更高。然而,这一想法是否正确?本文将通过一系列测试,来客观对比这两种方法的效果,从而证明YuNet在各方面已经远远超越了传统分类器方法:
- 测试平台:Windows10 x64 Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz 1.61 GHz
- 测试参数:基于Haar特征的级联分类器: 使用默认值(ScaleFactor=1.1, MinNeighbors=2)YuNet: 使用默认值(ConfThreshold=0.9, NmsThreshold=0.3)
- 平均耗时测量方法:重复执行检测部分100次,取平均时间
对比测试 1:
测试图像大小:320*320
测试结果:
模型 | 检测人脸数目 | 平均耗时 |
Cascade Classifier | 8 | 25.81ms |
YuNet | 8 | 5.09ms |
两者对简单清晰无遮挡的人脸都有着不错的检测率,都成功识别了全部8个人脸。
在耗时上,YuNet消耗时间远少于传统方法,效率是传统方法的5倍。
对比测试 2:
测试图像大小:320*320
测试结果:
模型 | 检测人脸数目 | 平均耗时 |
Cascade Classifier | 7 | 24.00ms |
YuNet | 10 | 5.36ms |
对比测试2中,测试图像包含部分侧脸、遮挡住的人脸,由此针对性地反映检测模型对于此类人脸的检测能力。
YuNet正确识别的人脸数为10个,而传统方法为7个。从这一测试中可以看出YuNet对于被遮挡的面部、非正脸面部的检测较传统方法更为优秀。
耗时结果与上一个测试相类似。
对比测试 3:
测试图像大小:320*320
测试结果:
模型 | 检测人脸数目 | 平均耗时 |
Cascade Classifier | 7 | 24.58ms |
YuNet | 37 | 5.12ms |
对比测试3使用世界最大的自拍中截取图像作为测试结果,由此考验检测模型对于不同尺寸人脸的检测能力。
从结果中可以明显看到,传统结果正确检测到了6张尺寸较大的人脸,却无法检测到中部以及后方的人脸,且存在一个误检测,检测率较低;而虽然YuNet也难以检测到后方较小的人脸,但是在图像前半部分正确检测到了37张脸,是传统方法的6倍数量。由此可以总结YuNet对于各尺寸的人脸兼容性优于传统分类器。
耗时结果上来看,YuNet效率依旧远超传统方法,且从这里可以看出,对一张320*320图像进行人脸检测,传统方法的耗时在25ms附近,而YuNet可以一直保持在5ms左右的水平。
对比测试 4:
测试图像大小:640*640
测试结果:
模型 | 检测人脸数目 | 平均耗时 |
Cascade Classifier | 29 | 111.26ms |
YuNet | 137 | 22.32ms |
测试4想通过放大图像尺寸来检验YuNet的优势是否还可以保持住。
可以明显注意到在图像尺寸放大之后,Haar特征分类器正确地检测到了更多人脸,但是这一提升依旧难以与YuNet的提升相提并论:在这次测试中,传统方法正确识别了29张人脸,而YuNet可以识别137张人脸。
两者的效率依旧存在显著的差距,从耗时结果来看,当图像尺寸增长时,YuNet的耗时依旧远低于传统方法。
总结
从以上几个测试来看,YuNet具备了以下优势:
- 有更好的检测率和效率。
- 可以检测被遮挡的面部以及侧脸。
- 更为轻量,文件大小更小。如‘facedetectionyunet2022mar.onnx’的文件大小为337 KB,而传统方法中相对应的‘haarcascadefrontalface_default.xml’大小为908KB。
- 参数简单易调,传统方法参数需要根据图片大小、人脸数量、人脸大小等一系列变量来不断调节以达到最好效果,而YuNet使用默认参数即可解决大部分情景。
- 效率稳定,在同一尺寸下,传统方法耗时与参数紧密相关,而YuNet检测人脸的耗时更短且较为固定。
基于CNN的YuNet在各方面表现结果都优于基于Haar特征的级联分类器,在选用人脸检测模型时,应该首先考虑选择基于CNN的YuNet。
部分代码
Haar cascade classifier
import cv2
import time
img = cv2.imread('test_pics/selfie640.png')
k = 100
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
tic = time.perf_counter()
# Convert into grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect faces
for i in range(1, k):
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3)
toc = time.perf_counter()
YuNet
import cv2 as cv
import numpy as np
from yunet import YuNet
import time
img = cv.imread('test_pics/selfie640.png')
k = 100
model = YuNet(modelPath='face_detection_yunet_2022mar.onnx',
inputSize=[320, 320],
confThreshold=0.9,
nmsThreshold=0.3,
topK=5000,
backendId=3,
targetId=0)
h, w, _ = img.shape
# Inference
model.setInputSize([w, h])
tic = time.perf_counter()
for i in range(1, k):
results = model.infer(img)
toc = time.perf_counter()
引用
测试图像均截取于World's Largest Selfie以及Wider Face数据集。
—THE END—
下载1:Pytorch常用函数手册
在「OpenCV与AI深度学习」公众号后台回复:Pytorch函数手册,即可下载学习全网第一份Pytorch函数常用手册,包括Tensors介绍、基础函数介绍、数据处理函数、优化函数、CUDA编程、多处理等十四章内容。
下载2:145个OpenCV实例应用代码
在「OpenCV与AI深度学习」公众号后台回复:OpenCV145,即可下载学习145个OpenCV实例应用代码(Python和C++双语言实现)。