【OpenCV応用編 第2回】群衆の中から人を見つけ出す!歩行者検出(全身検出)に挑戦しよう 🚶

「顔が隠れていても、そこに『人』がいることを認識させたい!」
「監視カメラの映像から、人の数を数えるにはどうすればいいの?」
「顔検出以外にも、物体を検出する別の方法ってあるの?」

こんにちは! OpenCV探検隊、隊長のPythonistaです! 前回の第1回では、顔というターゲットをさらに深掘りし、「目」や「笑顔」といった細かいパーツを検出する方法を学びましたね。

シリーズ第2回となる今回は、逆にグッと視野を広げて、人物の**「全身」**を検出する**歩行者検出 (Pedestrian Detection)** に挑戦します! これにより、あなたのプログラムは、カメラからの距離が遠かったり、人物が横を向いていたりして顔が見えなくても、その存在を捉えることができるようになります。この技術は、街中の人流解析や、セキュリティシステム、自動運転技術など、非常に多くの分野で活用されているんですよ。さあ、群衆の中から個人を認識する、新たなステップに進みましょう!


1. 今回の新しい武器:HOG + SVM

前回の顔や目の検出では、「ハールカスケード分類器」という武器を使いました。実は、全身を検出するためのハールカスケード(`haarcascade_fullbody.xml`)も存在するのですが、今回はより一般的に歩行者検出で高い性能を発揮する、別の強力な武器を紹介します。

それが、**HOG (Histogram of Oriented Gradients) 特徴量 + SVM (Support Vector Machine)** という組み合わせです。

  • HOG特徴量とは?
    ハールカスケードが画像の「明暗のパターン」を見ていたのに対し、HOGは**「輪郭の向きのパターン」**を見ます。画像の中の明るさが変化する方向(勾配)をたくさん集計し、「人の形は、だいたいこういう向きの輪郭線で構成されているよね」という特徴を捉えます。
    例えるなら… ハールカスケードが「目と鼻の位置関係」で見分ける刑事なら、HOGは「全身のシルエット」で見分ける凄腕の探偵のようなものです。

  • SVMとは?
    SVMは、HOGによって抽出された「輪郭のパターン」が、果たして「人」のものなのか、それとも「人でない」ものなのかを、高い精度で識別してくれる、非常に賢い分類器(機械学習モデル)です。

難しく聞こえるかもしれませんが、ご安心ください。OpenCVには、このHOG+SVMを使って**人物を検出するために、あらかじめ訓練されたモデル**が標準で組み込まれています。私たちは、それを呼び出すだけで良いのです!


2. 実装:リアルタイム歩行者検出プログラム

それでは、Webカメラの映像からリアルタイムで歩行者を検出するプログラムを作成します。今回は、外部のXMLファイルは不要で、OpenCVに内蔵された機能だけで完結します。

import cv2
import sys

# --- ステップ1: HOG特徴量の初期化 ---
# HOG特徴量を計算するためのオブジェクトを生成
hog = cv2.HOGDescriptor()
# OpenCVに標準で用意されている、訓練済みの人物検出器をセット
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# Webカメラに接続
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("エラー: Webカメラを開けませんでした。")
    sys.exit()

print("リアルタイム歩行者検出を開始します...'q'キーで終了します。")

# --- メインループ ---
while True:
    ret, frame = cap.read()
    if not ret:
        break
        
    # --- ステップ2: 歩行者検出の実行 ---
    # detectMultiScaleメソッドで、画像中から人物を検出する
    # winStride: 検出ウィンドウのスライド幅。小さいほど丁寧だが遅くなる。
    # padding: 検出領域の周囲の余白。
    # scale: 画像のスケール。1.05は5%ずつ縮小して探すという意味。
    # found_rects: 検出された矩形のリスト
    # weights: 各矩形の信頼度スコア
    found_rects, weights = hog.detectMultiScale(
        frame, 
        winStride=(4, 4), 
        padding=(8, 8), 
        scale=1.05
    )
    
    # --- ステップ3: 検出した人物を矩形で囲む ---
    for i, (x, y, w, h) in enumerate(found_rects):
        # 信頼度スコアを取得して、矩形と一緒に表示する(任意)
        confidence = weights[i]
        if confidence > 0.5: # 信頼度が0.5以上のものだけ描画
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cv2.putText(frame, f"Person: {confidence:.2f}", (x, y - 10), 
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    # 結果を表示
    cv2.imshow('Real-time Pedestrian Detection', frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# --- 後片付け ---
cap.release()
cv2.destroyAllWindows()


このスクリプトを実行し、Webカメラの前で少し離れて立ってみてください。あなたの全身が緑色の矩形で囲まれるはずです。ハールカスケードを使った顔検出と比べて、少し処理が重いかもしれませんが、より遠くの人物や横向きの人物も認識できることがあるのが分かると思います。

コードのポイント:

  • cv2.HOGDescriptor(): HOG特徴量を計算するための検出器を初期化します。
  • hog.setSVMDetector(...): OpenCVが提供する、訓練済みの人物検出用SVMモデルをセットします。この一行で、検出器が「人物のシルエット」を知っている状態になります。
  • hog.detectMultiScale(...): この関数が、実際に画像から人物を検出します。ハールカスケードの時と似ていますが、検出された矩形のリストと一緒に、それぞれの「信頼度スコア」も返してくれます。このスコアを使えば、確信度の低い検出結果を除外するといった、より高度な制御が可能になります。

まとめと次回予告

今回は、OpenCV応用編の第2回として、ハールカスケードとは異なるアプローチである**HOG特徴量**を使い、人物の全身を検出する方法を学びました。

  • 画像の「輪郭の向きのパターン」を捉える**HOG特徴量**という新しい武器を知った。
  • OpenCVに標準搭載されている、訓練済みの**人物検出器**を簡単に呼び出す方法。
  • 検出結果に付随する**信頼度スコア**を使い、より確かな結果だけをフィルタリングする方法。

顔、目、笑顔、そして全身。これであなたは、画像や映像の中から「人」に関する様々な情報を抽出するための、強力なツールキットを手に入れました。

さて、個別の検出技術は十分に揃いました。次回、応用編の最終回では、いよいよこれらの技術を組み合わせる**「合わせ技」**に挑戦します!

具体的には、「**まず映像の中から歩行者(全身)を検出し、その人物がカメラに近づいて顔が認識できるようになったら、さらにその人が笑顔かどうかを判定する**」という、複数の検出器を連携させる複合的なアプリケーションを作成します。お楽しみに!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ入門 第3回】データ交換の標準!jsonモジュールでJSONを自由自在に扱おう