OpenCVで顔検出

OpenCVで顔検出したい場合(Haar-like 特徴を用いたカスケード分類器)の実装方法を解説します。

images/cards/lena.webp

目次

OpenCV で顔検出したい

OpenCV で用意されている Haar-like 特徴を用いたカスケード分類器により、顔検出を実施します。 対象画像から探索窓毎に 複数の Haar-like 特徴を計算し、顔パターンがあるかないかをカスケード分類器により判定します。

OpenCVで顔検出1

Haar-like 特徴

Haar-like 特徴とは、下図のように明暗で構成される矩形のパターンを用いて、複数の局所領域における白色の画素の輝度値の輪と黒色の画素の輝度値の和の差を特徴量としたものです。

OpenCVで顔検出2

カスケード分類器

カスケード分類器とは、複数の識別器を連鎖的に繋げて組み合わせた分類器のことです。 アンサンブル学習の一つであり、全識別器による識別で顔領域とみなされたものを顔が写っている領域であるとみなします。 OpenCV では、あらかじめいくつかの事前に学習を済ませた識別器が提供されています。例えば顔、目、笑顔検出のための検出器です。 これらは、OpenCV のインストールフォルダの「opencv/data/haarcascades」に保存されている XML ファイルに保存されています。 こちらかもダウンロードできます。

detectMultiScale のパラメータ調整

scaleFactor

スキャン毎にスケーリングされる探索窓のスケーリングファクタです。例えばこれが 1.1 なら,探索窓が 10 % 大きくなります。 探索窓が大きいほど、処理時間は少なく済む一方、探索窓が小さければ、処理時間は多くかかります。 探索窓が大きいほど、誤検出が多くなる一方、探索窓が小さければ、未検出が多くなります。

minNeighbor

スキャンした結果、同じ領域で重複して検出されなければいけない最低必要な数になります。 値が大きいほど、顔領域である信頼性が高く、誤検出が少なくなる一方、未検出が多くなってしまいます。 値が小さいほど、顔領域である信頼性が低く、誤検出が多くなる一方、未検出が少なくなります。

minSize

顔領域の取り得る最小サイズです。これよりも小さい領域は無視されます。

Python での実装

import cv2

# 入力画像の読み込み
img = cv2.imread("lena.jpg", cv2.IMREAD_COLOR)

# カスケード型識別器の読み込み
cascade_face = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

# カラー画像からグレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 顔領域の探索
faces = cascade_face.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50))

# 顔領域を赤色の矩形で囲む
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0,0,255), 3)

# 結果を出力
cv2.imwrite("result.jpg",img)

関連記事