天天看点

OpenCV人脸检测:级联分类器与YuNet效果对比

陈张杰

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

OpenCV人脸检测:级联分类器与YuNet效果对比

人脸检测技术是指对于任意一幅给定的图像,通过计算机算法对其进行搜索以确定其中是否含有人脸,如果其中包含人脸则标定人脸的位置、大小等特征。这项技术近年来非常火热,而这项技术的普及也带来了对于检测率、效率等各方面的需求,这些需求也影响了人们对于模型的选择。

基于Haar特征的级联分类器(Haar Feature-based Cascade Classifier)于2001年被提出,这是一种经典的人脸检测算法,通过Haar特征有效地检测对象,通过积分图来提高图像特征值计算的效率,通过AdaBoost算法来训练一个强分类器。一直以来这项技术凭借着快速、出色的检测效果在人脸检测方面获得了广泛的应用。

OpenCV人脸检测:级联分类器与YuNet效果对比

基于卷积神经网络的YuNet于2018年12月发布,2019年3月开源。它是一个强大的、轻量级的人脸检测模型,可以装载在大部分设备上运行。YuNet的人脸检测速度可达到1000fps,并且可以检测很多较难检测的对象,如被遮挡的人脸、侧脸等。

OpenCV人脸检测:级联分类器与YuNet效果对比

当技术使用者需要一个模型来进行人脸检测时,到底是继续沿用传统分类器模型,还是改用基于神经网络的新方法,成为了一个令人纠结的问题。很多人会认为传统方法训练简单,消耗的计算力更少,检测人脸速度更快,效率更高。然而,这一想法是否正确?本文将通过一系列测试,来客观对比这两种方法的效果,从而证明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

测试结果:

OpenCV人脸检测:级联分类器与YuNet效果对比
模型 检测人脸数目 平均耗时
Cascade Classifier 8 25.81ms
YuNet 8 5.09ms

两者对简单清晰无遮挡的人脸都有着不错的检测率,都成功识别了全部8个人脸。

在耗时上,YuNet消耗时间远少于传统方法,效率是传统方法的5倍。

对比测试 2:

测试图像大小:320*320

测试结果:

OpenCV人脸检测:级联分类器与YuNet效果对比
模型 检测人脸数目 平均耗时
Cascade Classifier 7 24.00ms
YuNet 10 5.36ms

对比测试2中,测试图像包含部分侧脸、遮挡住的人脸,由此针对性地反映检测模型对于此类人脸的检测能力。

YuNet正确识别的人脸数为10个,而传统方法为7个。从这一测试中可以看出YuNet对于被遮挡的面部、非正脸面部的检测较传统方法更为优秀。

耗时结果与上一个测试相类似。

对比测试 3:

测试图像大小:320*320

测试结果:

OpenCV人脸检测:级联分类器与YuNet效果对比
模型 检测人脸数目 平均耗时
Cascade Classifier 7 24.58ms
YuNet 37 5.12ms

对比测试3使用世界最大的自拍中截取图像作为测试结果,由此考验检测模型对于不同尺寸人脸的检测能力。

从结果中可以明显看到,传统结果正确检测到了6张尺寸较大的人脸,却无法检测到中部以及后方的人脸,且存在一个误检测,检测率较低;而虽然YuNet也难以检测到后方较小的人脸,但是在图像前半部分正确检测到了37张脸,是传统方法的6倍数量。由此可以总结YuNet对于各尺寸的人脸兼容性优于传统分类器。

耗时结果上来看,YuNet效率依旧远超传统方法,且从这里可以看出,对一张320*320图像进行人脸检测,传统方法的耗时在25ms附近,而YuNet可以一直保持在5ms左右的水平。

对比测试 4:

测试图像大小:640*640

测试结果:

OpenCV人脸检测:级联分类器与YuNet效果对比
模型 检测人脸数目 平均耗时
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++双语言实现)。

继续阅读