OpenCVのHOGDescriptorクラスを使った人物検出
概要
OpenCVのHOGDescriptorクラスは、画像や動画から人物を検出するための強力なツールです。このクラスはHistogram of Oriented Gradients(HOG)という特徴量を使用しています。HOGは、画像の局所的な勾配方向のヒストグラムを特徴量として使用し、これにより人物の形状を捉えることができます。HOGDescriptorクラスは、セキュリティカメラの映像から人物を検出したり、自動運転車が歩行者を認識するために使用したりすることができます。また、SNSの写真から人物を自動的にタグ付けするためのアルゴリズムにも使用することができます。
出力結果
元の画像 |
出力結果 |
プログラム全体
#解説1
import cv2
import numpy as np
from matplotlib import pyplot as plt
#解説2
# 画像をロードし、色空間をRGBに変換します
img = cv2.imread('human_sample3.jpeg')
# OpenCVのデフォルトの色空間BGRからRGBに変換
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#解説3
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
boxes, weights = hog.detectMultiScale(img, winStride=(4, 4), padding=(8, 8), scale=1.04)
#解説4
# 検出された人物を囲む矩形を描画し、画像を表示します
for (x, y, w, h) in boxes:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
plt.imshow(img)
plt.show()
解説
解説1:必要なライブラリのインポート
import cv2
import numpy as np
from matplotlib import pyplot as plt
この部分では、プログラムで必要となるライブラリをインポートしています。ライブラリは、特定の機能を提供するコードの集合で、これにより画像処理や数値計算などの複雑な操作を簡単に行うことができます。
cv2 |
OpenCVという画像処理ライブラリのPythonバージョンです。画像の読み込みや色空間の変換、人物の検出など、画像に関する様々な操作を提供します。 |
---|---|
numpy |
数値計算を効率的に行うためのライブラリです。大量の数値データを高速に処理するために使用します。 |
matplotlib.pyplot |
グラフの描画や画像の表示など、視覚的な出力を提供するライブラリです。 |
解説2:画像の読み込みと色空間の変換
img = cv2.imread('human_sample3.jpeg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ここでは、cv2.imread
関数を使用して画像を読み込んでいます。読み込んだ画像は、色の情報を持つピクセルの配列として表現されます。次に、cv2.cvtColor
関数を使用して色空間を変換しています。OpenCVでは、色は通常、青、緑、赤の順(BGR)で表現されますが、Pythonの他のライブラリでは赤、緑、青の順(RGB)で色を表現することが一般的です。そのため、この変換が必要となります。
解説3:HOG記述子の作成と人物の検出
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
boxes, weights = hog.detectMultiScale(img, winStride=(4, 4), padding=(8, 8), scale=1.04)
この部分のコードは、画像から人間を見つけるための特別なツールを使っています。そのツールの名前は「HOG」と「SVM」です。
まず、「HOG」はHistogram of Oriented Gradients(方向勾配ヒストグラム)の略で、画像の特定の部分を見つけるために使われます。HOG(Histogram of Oriented Gradients)記述子という特徴量を使用して画像から人物を検出しています。HOG記述子は、画像の局所的な勾配方向のヒストグラムを特徴量として使用します。
次に、SVMで、HOGが見つけた勾配のパターンが本当に人間のものかどうかを判断します。これは、以前に人間の画像をたくさん見て学習した知識を使っています。そして、detectMultiScale
関数は、画像の中にいくつかの人間がいるかもしれないと考え、画像の様々な個所をHOGとSVMを使って人間を探しています。winStride
は、画像をどのくらいのステップで移動しながら探すか、padding
は、探す窓の周りにどのくらい余白を持たせるか、scale
は、探す窓のサイズをどのくらい変えるかを決めます。
最終的に、このコードは画像の中から人間を見つけ、その位置を矩形のリスト(boxes
)として返します。これらの矩形は、後で画像に描画され、人間が見つかった場所を表しています。
補足:hog.detectMultiScaleの引数について
hog.detectMultiScale
関数は、画像内の物体(この場合は人間)を検出するための関数です。この関数はいくつかの引数を取ります:
img |
検出を行う画像です。 |
---|---|
winStride |
これは検出窓が画像上をどれだけ移動するかを決定します。例えば、(4, 4) のときは、検出窓が水平方向にも垂直方向にも4ピクセルずつ移動することを意味します。この値が小さいほど、検出はより詳細になりますが、計算時間が増えます。 |
padding |
検出窓の周りに追加される余白の量を示しています。余白は、検出窓が画像の端に達したときに物体の一部が切り取られるのを防ぐために使用されます。 |
scale |
検出窓のサイズをどれだけ変更するかを示しています。物体が画像内の異なる位置や距離で存在する可能性があるため、異なるスケールで検出を行うことは重要です。この値が大きいほど、より大きなスケールの変化を試みますが、計算時間が増えます。 |
これらの引数を調整することで、検出の精度と計算時間のバランスを調整することができます。
解説4:検出結果の描画と表示
for (x, y, w, h) in boxes:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
plt.imshow(img)
plt.show()
最後に、検出された人物を囲む矩形を描画し、画像を表示しています。cv2.rectangle
関数で画像に矩形を描画し、plt.imshow
とplt.show
で画像を表示しています。これにより、どの部分に人物が検出されたかを視覚的に確認することができます。
おまけ
HOG
とCascade
は、どちらも画像から特定の物体を見つけ出すためのツールですが、その方法は少し異なります。
まず、HOG
は「Histogram of Oriented Gradients」の略で、これは画像の「勾配」(色や明るさがどのように変化するか)の情報を利用します。例えば、人の顔の形や体の形は、色や明るさが特定のパターンで変化するため、これを利用して人を見つけ出すことができます。HOG
は、画像全体を小さな「窓」に分けて、それぞれの窓で勾配の情報を集め、その情報を使って物体を認識します。
一方、Cascade
は「カスケード分類器」という方法を使います。これは、あらかじめ人の顔の特徴を学習した「分類器」を使って、画像の中から人の顔を見つけ出します。分類器は、人の顔の特徴(目や鼻、口など)が画像のどの部分にあるかを調べ、それが人の顔に一致するかどうかを判断します。
要するに、HOG
は画像の「勾配」の情報を使って物体を認識し、Cascade
は学習した「人の顔の特徴」を使って人の顔を認識します。それぞれ異なる方法で物体を認識するため、使い方や適用する場面も異なります。
下記ではUVCカメラとカスケード分類器を組み合わせて人の顔を検知するプログラムも紹介しています。
https://www.argocorp.com/UVC_camera/Sample_OpenCV_cascade.detectMultiScale.html