(現在2.4.7になっており内容が異なっているので、2.4.6限定の話である。
また、調査した時期も数カ月前なのでoclを考慮していない)
OpenCV2.4.6のHOGのソースは、
modules\objdetect\src\hog.cpp
であり、CPU版のサンプルは、
samples\cpp\peopledetect.cpp
GPU版のサンプルは、
samples\gpu\hog.cpp
である。
OCL版も準備されているが、OCLの環境がないため無視する。
CPU版のソースをみると計算される特徴量は、
INRIA Object Detection and Localization Toolkit
(http://pascal.inrialpes.fr/soft/olt/)
と互換性があるとのことだが、オリジナルが英語なので現在未読である。
サンプルプログラムの内容
CPU版のサンプルプログラムで、HOG関連をひらっていくと
インスタンスの作成
Line48で、HOGDescriptor hog;
辞書の設定
Line49で、hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
検出処理
Line79で、hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
検出結果は、cv::vector<Rect> foundに格納される
検出した領域の重複検査を行い、重複がない場合のみ、cv::vector<Rect> found_filteredに格納されている。(Line 83-91)
また、オリジナルの辞書は、人の周りの余白が多いため、表示の時に検出された領域を縮小している。(Line 92-102)
以上のような処理を行っている。
HOG関数
なぜか、CPU版のドキュメントは準備されていない。Webで検索するとGPU版の説明のみHitする。
HOGDescriptorには、各種パラメータが設定できるようになっているが、コードの実装は固定値を使用しており、自由に変更できない
CELLサイズ 8x8のみサポート
BLOCKサイズ 16x16のみサポート
BINサイズ 9bins
BLOCK移動量 CELLサイズの整数倍
また、入力画像にガンマ補正処理のフラグがあり、デフォルトではtrueとなっている
Line49 API名は、setSVMDetectorとなっているが、HOGDescriptor::getDefaultPeopleDetector()の戻り値は、static std::vector<float>であり、
実際の処理は検出用の辞書データを設定している。
CPU版のソースでgetDefaultPeopleDetectorをみてみると
vector<float> HOGDescriptor::getDefaultPeopleDetector()
{
static const float detector[] = {
以下 辞書データをそのままfloatの配列に書き込んでいる
一見、辞書の差し替えができる構造に見えるが、辞書作成用のHOG + SVMのツールは、提供されていないので、INRIA Object Detection and Localization Toolkitで
自力で作成する必要がある。
あとドキュメント化されていないようだが、getDefaultPeopleDetectorの辞書に登録されている画像データのサイズは64x128画素であり、
この大きさより、小さい人物を検出したい場合は、対象の画像を拡大しないといけない。
拡大すると、検出精度が低下するため、別途48x96画素の辞書データが準備されている
その場合、HOGDescriptor::getDaimlerPeopleDetector()を使用しないといけない
HOG関数内での基本処理
ガンマ補正
縦、横の3x3のsobelフィルター
角度と長さの計算
blockのヒストグラム計算
ヒストグラムの正規化
SVMの計算
マルチスケールで各スケール画像で領域を検出した後、領域を統合する必要がある
計算コストの関係で、meansiftが使用されるとのこと
ソース内部でも
if ( useMeanshiftGrouping )
{
groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize);
}
else
{
groupRectangles(foundLocations, (int)finalThreshold, 0.2);
のように使用されている
groupRectangles_meanshiftは、cascadedetect.cppで定義されており、自作プログラムからは、cv::groupRectangles_meanshiftで呼び出すことが可能である。
しかし、ドキュメントには説明はないので、なくなる可能性もある
//new grouping function with using meanshift
static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights,
vector<double>& scales, Size winDetSize)
関数内部では、MeanshiftGroupingクラスが使用されており、計算はこのクラスで行っているようだ。
関連ドキュメント
- fastHOG - a real-time GPU implementation of HOG
- Computer Vision on GPU with OpenCV
- GPU & CPU Cooperative Accelerated Pedestrian and Vehicle Detection
- OpenCV on a GPU
- 統計的学習手法による人検出
- 局所特徴量と統計学習手法による物体検出
0 件のコメント:
コメントを投稿