天天看點

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++雙語言實作)。

繼續閱讀