カスケード分類器を用いた顔検出#

このコンピュータビジョンの例では、機械学習に基づいた物体検出フレームワークを使用して、画像上の顔を検出する方法を示します。

まず、トレーニングされたデータを読み取ることができるxmlファイルが必要です。このフレームワークは、マルチブロック局所二値パターン機能(MB-LBPを参照)と注意カスケード付きGentle Adaboostを使用してトレーニングされたファイルで動作します。したがって、検出フレームワークは、OpenCVからのxmlファイルでも動作します。そこには、猫の顔、横顔、その他のものを検出するようにトレーニングされたファイルがあります。ただし、正面の顔を検出する場合は、scikit-imageにすでに該当するファイルが含まれています。

次に、detect_multi_scale関数のパラメーターを指定する必要があります。ここでは、それぞれの意味を見つけることができます。

最初はscale_ratioです。すべての顔を見つけるために、アルゴリズムは複数のスケールで検索を行います。これは、検索ウィンドウのサイズを変更することで行われます。最小ウィンドウサイズは、トレーニングで使用されたウィンドウのサイズです。このサイズは、トレーニングされたパラメーターを含むxmlファイルで指定されています。scale_ratioパラメーターは、各ステップで検索ウィンドウが増加する比率を指定します。このパラメーターを大きくすると、検索時間が短縮され、精度が低下します。したがって、一部のスケールの顔は検出されない可能性があります。

step_ratioは、画像の各スケールで顔を検索するために使用されるスライディングウィンドウのステップを指定します。このパラメーターが1に等しい場合、可能なすべての場所が検索されます。パラメーターが1より大きい場合(たとえば、2)、ウィンドウは2ピクセル移動し、可能なすべての場所が顔の検索対象になりません。このパラメーターを大きくすることで、アルゴリズムの作業時間を短縮できますが、精度も低下します。

min_sizeは、スケール検索中の検索ウィンドウの最小サイズです。max_sizeは、ウィンドウの最大サイズを指定します。検索する画像の顔のサイズがわかっている場合は、これらのパラメーターをできるだけ正確に指定する必要があります。高価な計算を回避し、誤検出の数を減らすことができるためです。min_sizeパラメーターを大きくすることで、多くの時間を節約できます。ほとんどの時間は最小スケールでの検索に費やされるためです。

min_neighbor_numberパラメーターとintersection_score_thresholdパラメーターは、同じ顔の過剰な検出をクラスター化し、誤検出をフィルタリングするために作成されています。真の顔は通常、周囲に多くの検出があり、偽の顔は通常、単一の検出があります。最初に、アルゴリズムはクラスターを検索します。2つの長方形の検出の間の交差スコアがintersection_score_thresholdよりも大きい場合、2つの長方形の検出は同じクラスターに配置されます。交差スコアは、(交差領域)/(小さな長方形の比率)の式を使用して計算されます。説明した交差基準は、小さな長方形が大きな長方形の内側にある場合に交差スコアが小さくなるというコーナーケースを回避するために、union over intersectionよりも選択されました。次に、各クラスターはmin_neighbor_numberパラメーターを使用してしきい値処理され、同じまたはそれ以上の検出数を持つクラスターが残ります。

誤検出は避けられないことにも注意する必要があります。本当に正確な検出器が必要な場合は、OpenCV train cascadeユーティリティを使用して自分でトレーニングする必要があります。

plot face detection
from skimage import data
from skimage.feature import Cascade

import matplotlib.pyplot as plt
from matplotlib import patches

# Load the trained file from the module root.
trained_file = data.lbp_frontal_face_cascade_filename()

# Initialize the detector cascade.
detector = Cascade(trained_file)

img = data.astronaut()

detected = detector.detect_multi_scale(
    img=img, scale_factor=1.2, step_ratio=1, min_size=(60, 60), max_size=(123, 123)
)

fig, ax = plt.subplots()
ax.imshow(img, cmap='gray')

for patch in detected:
    ax.axes.add_patch(
        patches.Rectangle(
            (patch['c'], patch['r']),
            patch['width'],
            patch['height'],
            fill=False,
            color='r',
            linewidth=2,
        )
    )

plt.show()

スクリプトの合計実行時間:(0分0.481秒)

Sphinx-Galleryによって生成されたギャラリー