0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

dlibとOpenCVのそれぞれで顔検出した結果比較

Last updated at Posted at 2021-02-22

はじめに

google-image-downloadで取得した画像ファイルから、学習用の顔画像をファイルに保存するために、OpenCVのHaarCascadeとdlibのface Detetor(HOG)を試して、性能を比較してみました。

開発環境

Ubuntu 18.04.4 LTS
Python 3.6.9
opencv 4.5.1
dlib 19.21.1

比較結果

入力画像ファイル数 正しく検出した顔の数 誤検出した数 処理時間
OpenCV HaarCascade 468 278 8 real 0m28.000s
dlib Face Detector(HOG) 468 841 9 real 9m43.149s
入力画像に含まれている顔の数は様々です。
誤検出したどうかは、切り出し後の画像を目視して確認しました。
  • こちらが検出前のダウンロード画像の一部
    切り出し前.jpg

  • こちらが検出後に保存した画像の一部
    切り出し後.jpg

ソースコード


#!/usr/bin/env python3

import cv2
import dlib
import sys
import os
import argparse
import logging

logger = logging.getLogger()

SAVED_IMAGE_SIZE = (200, 200)

class faceDetector:
	pass

class HaarDetector(faceDetector):
	def __init__(self):
		self.__detector = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml')
	def run(self, img):
		return self.__detector.detectMultiScale(img, 1.08, 5, minSize=SAVED_IMAGE_SIZE)
	def getVertexes(self, face):
		(x, y, w, h) = face
		return (x, y, w, h)

class HogDetector(faceDetector):
	def __init__(self):
		self.__detector = dlib.get_frontal_face_detector()
	def run(self, img):
		return self.__detector(img, 1)
	def getVertexes(self, face):
		x0 = max(0, face.left())
		y0 = max(0, face.top())
		x1 = max(0, face.right())
		y1 = max(0, face.bottom())
		return (x0, y0, x1-x0+1, y1-y0+1)

OpenCV HaarCascadeとglib face detectorのインタフェース差異を吸収するためにfaceDetectorクラスを作成しました。
以下の関数で、入力画像ファイルから顔認識を行い、認識した領域をファイルに保存します。


def detectAndSaveFace(input_dir, output_dir, useHaar):
	logging.basicConfig(level=logging.INFO, format='%(message)s')

	if useHaar:
		detector = HaarDetector()
	else:
		detector = HogDetector()

	files_processed = 0
	faces_detected = 0

	for filename in os.listdir(input_dir):
		orig_img = cv2.imread(os.path.join(input_dir, filename), cv2.IMREAD_GRAYSCALE)	
		if orig_img is None:
			logger.warning('ignoring {0}'.format(filename))
			continue

		faces = detector.run(orig_img)
		logger.debug('Detected({0}) in {1}'.format(len(faces), filename))
		files_processed += 1

		# Save the detected bounding boxes
		for face in faces:
			(x, y, w, h) = detector.getVertexes(face)
			face_img = cv2.resize(orig_img[y:y+h, x:x+w], SAVED_IMAGE_SIZE)
			face_filename = '{0}/{1}.pgm'.format(output_dir, faces_detected)
			cv2.imwrite(face_filename, face_img)
			faces_detected += 1

	logger.info('files processed = {0}, faces detected = {1}'.format(files_processed, faces_detected))

余談

正面を向いた顔画像を保存したかったので、dlibのCNNは試しませんでした。
dlibで検出した画像範囲の座標がマイナスになる場合がありました。

最後に

dlibのHOGによる検出精度が良いのは想定通りでしたが、私のPCでは予想以上に処理時間がかかりました。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?