目的
OpenCV
の顔検知とdlib
の顔検知はどちらの方が(処理が)軽いのかを調べる
動機
現在作っているCj-bc/Face-data-serverで参考にしていたコードでは、場所によってdlib
とOpenCV
を使い分けていました。
自分のコードを書いている時に、何か理由があるのか気になったので、「実行速度」という観点から何か違いがあるのかを調べてみることにしました。
検証
環境
(2019/10/25 追記)
処理系: 1.2GHz デュアルコアIntel Core m5
方法
以下のコードを用いて、各項目毎100回の平均値を比較しました。
又、OpenCV
のカスケードファイルはCj-bc/Face-data-server -- face_detection/haarcascades/haarcascade_frontalface_default.xmlです
import time
import cv2
import dlib
from functools import reduce
# prepare dlib and cv2
face_cascade = cv2.CascadeClassifier('<PATH_TO_REPO>/face_detection/haarcascades/haarcascade_frontalface_default.xml')
detector = dlib.get_frontal_face_detector()
def ptime(f, arg):
"""Record how much time does f(arg) take"""
s_time = time.time()
f(arg)
return (time.time() - s_time)
cap = cv2.VideoCapture(0)
# with face
input("show face to the camera")
_, frame = cap.read()
# with no face
input("Then, hide your face plz")
_, nofaceFrame = cap.read()
cap.release()
# helper wrapper to repeat ptime for 100 times and calculate average
result = lambda f, arg: reduce(lambda prev, n: prev + ptime(f, arg), range(100), 0.0) / 100
print("==== Gray scale ====")
print(f"cv2 with face : {result(face_cascade.detectMultiScale, gray)}")
print(f"cv2 with no face : {result(face_cascade.detectMultiScale, nofaceGray)}")
print(f"dlib with face : {result(detector, gray)}")
print(f"dlib with no face : {result(detector, nofaceGray)}")
print("==== original Color ====")
print(f"cv2 with face : {result(face_cascade.detectMultiScale, frame)}")
print(f"cv2 with no face : {result(face_cascade.detectMultiScale, nofaceFrame)}")
print(f"dlib with face : {result(detector, frame)}")
print(f"dlib with no face : {result(detector, nofaceFrame)}")
結果
==== Gray scale(include convert time) ====
cv2 with face : 0.13291994094848633
cv2 with no face : 0.03347130537033081
dlib with face : 0.043859701156616214
dlib with no face : 0.04444729089736939
==== original Color ====
cv2 with face : 0.12641916751861573
cv2 with no face : 0.03346560716629028
dlib with face : 0.061687271595001224
dlib with no face : 0.06083619832992554
考察
いいからdlibを使え(速度重視の場合)
OpenCV
は、顔が検出されない時はdlib
より速いものの、顔を検出するとなると圧倒的に遅くなることがわかりました。
その一方で、dlib
は安定した数値を出しているようです。
稀にしか顔検出を行わない場合などはOpenCV
の方が良い時がありそうですが、基本的にはdlib
を用いる方が安定しており得策かなと思いました。
又、これはおそらく学習データに依存した結果だと思うので他の場合も同様な結果になるのかはわかりません。
dlib
の場合、グレースケールの方が変換する時間を含めても速かったですがOpenCV
の場合はやや遅くなったことから、OpenCV
での検出を使う場合はグレースケール変換を行わないほうが良いようです。
ユースケース | 結果に基づくおすすめ |
---|---|
常時顔検出をし続ける | Dlib(グレイスケール) |
極偶に顔検出する | cv2 |
留意点
- このデータは以下の要素に依存する可能性があります。
- 使用した学習データ
- 実際に使用したキャプチャのフレーム