2015.11. 7..
石立 喬

OpenCVとVisual C++による画像処理と認識(13A)

----- HOGDescriptorとSVMで人(歩行者)を検出する -----

 「OpenCVとVisual C++による画像処理と認識(13)」では、カスケード分類器CascadeClassifierクラスからスタートし、haarcascade_frontalface_default.xml.やhogcascade_pedestrians.xmlなどの学習済みファイルを読み込むことにより、Haar-like特徴やHOG特徴に結び付けて、顔や人の検出を行った。
 これに対し、ここでは、HOGDescriptorクラスのHOG特徴から出発し、そこに備わっているgetSVMDetectorに訓練済みファイルを読み込んで、SVM分類器を使用した。学習済みファイルには、人検出用しかないので、人の検出に限られる。

HOGDescriptorクラスの使い方
 HOGDescriptorは、被探索画像を64 x 128などの単位でスキャンし、さらに、そこで、8 x 8などのセルを移動させて、HOG特徴の集まりを生成する。setSVMDetector関数で、あらかじめ作成された検出用データを読み込んでSVM分類器を用意しておく。
 検出の実行にはdetectMultiScale関数を用いる。ここで、前述のHOG特徴の集まりと検出用データを比較し、人であるか否かを判定する。 

ここで試みたHOGDescriptor設定のいろいろ
 OpenCVに備わっているHOGDescriptorrを用いて、人(歩行者)の検出を行うに際して、下記の様に設定を変えて、最適条件を求める。
  1)HOGDescriptorのコンストラクタで、検出ウィンドウサイズを下記の三種類から選ぶ。ブロックサイズなどのその他のサイズは、それぞれ、表1に従う必要がある。
     Size(64, 128) ------ デフォルト
     Size(48, 96) ------- Daimler使用時に使う
     Size(32, 64) ------- 筆者が試みて使用できた、今回使用した被検索画像に対しては、一番良かった

表1 HIOGDescriptorで使用可能な各サイズの組み合わせ


  2)setSVMDetector関数で、学習済みデータを、下記の二種類から選択する。組み合わせには、表2に示した制約がある。
    表2で、○は組み合わせ可能、×は組み合わせ不可を示す。
      getDefaultPeopleDetector() ------- ウィンドウサイズが 64 x 128の分類器の学習済み係数、vector<float>型
      getDaimlerPeopleDetector() ------- ウィンドウサイズが 48 x 96の分類器の学習済み係数、vector<float>型

表2 HOGDescriptorの検出ウィンドウ・サイズと使用できる分類用データ


  3)detectMultiScale関数で、下記パラメータを調節して、最適値を使用する。
     hitThreshold ------ 人と判断するしきい値、デフォルトは0であるが、マイナスにすると、感度が上がる。double型
     winStride --------- 検出ウィンドウをスキャンするステップで、デフォルトはSize(8, 8)である。小さくすると精度が上がる。
     findThreshold ----- 人と判断するに必要な、近傍の検出矩形の最低限の数。デフォルトは2であるが、これを増やすと、誤検出が減る。

HOGDescriptorとSVMを用いて人物(歩行者)を検出するプログラム
 図1は使用したプログラムで、下記から成っている。
 1)被探索画像を読み込む。
 2)被探索画像をグレイスケール化し、ヒストグラムを平坦化する。
 3)人の検出を行う。
   a) HOGDescriptorを生成する
       デフォルト、Daimler、ユーザー設定から選択する
   b) setSVMDetectorで、分類用データを読み込む
       デフォルト、Daimlerから選択する
   c) detectMultiScaleを実行する
       デフォルト、ユーザー設定から選択する
 4)検出結果を描画する

使用したOpenCV関数の説明
 OpenCV3.0.0-devなどの資料による。OpenCV2.4.12.0(最新?)には、gpu::HOGDescriptorやocl::HOGDescriptorしかない。
◎HOGDescriptorクラス
 このコンストラクタには、デフォルトがあり、  デフォルト・コンストラクタの場合は、
   _winSize = Size(16. 128) ----- 結果として人と判定する検出ウィンドウのサイズ
   _blockSize = Size(16, 16) ---- セルのコントラストを正規化するためのセルの範囲
   _blockStride = Size(8, 8) ----- 一回ごとに、検出ウィンドウを移動させる量、セルサイズの整数倍、ブロックサイズの半分
   _cellSize = Size(8, 8) -------- 検出ウインドウ内をスキャンしてヒストグラムを採るセルのサイズ
   _nbins = 9 ----------------- ヒストグラムの入れ物の数、ヒストグラムを採る方向の数、9のみサポート
となるが、その他のコンストラクタを用いる場合に、これらをデフォルト値として省略することはできない。
 別途設定する場合には下記の引数を与える。
   _winSiz ------- 上記で説明済み、デフォルト値でも、設定を省略できない
   _blockSize ----- 同上
   _blockStride ---- 同上
   _cellSize ------- 同上
   _nbins --------- 同上
   _derivAperture = 1 ------------ Sobelフィルタのアパーチャサイズ、デフォルトはフィルタを不使用
   _winSigma = -1 -------------- Gauss平滑フィルタのパラメータ、デフォルトはフィルタを不使用
   histogramNormType = 0 ------- HOGDescriptor::L2Hsy(L2-normの後で、最大値をクリップする)を使う
   _L2HysThreshold = 0.2 -------- 上記実行時のしきい値
   _gammaCorrection = false ------ ガンマ補正しないのがデフォルト
   _nlevels = 64 ---------------- 画像の拡大を繰り返す回数、デフォルトで良い
◎HOGDescriptor::detectMultiScale関数
 この関数は、被探索画像と探索窓との相対的なサイズを変えながら検出を繰り返すもので、引数は、
   img -------------- 被検索画像
   foundLocations ---- 検出結果出力矩形、vector<Rect>型
   hitThreshold = 0 --- この値より大の時、人と判断する、負数にすることも可。double型
   winStride = Size() -- ウィンドウを移動させる一回のピクセル数、デフォルトは8 x 8、小さくすると精度が上がるが、遅くなる
   padding = Size() --- 入力画像の周辺を拡張する範囲、周辺部の検出を可能にする
   scale = 1.05 ------ 一回のスキャンごとに画像を拡大する拡大率
   findThreshold = 2 -- これ以上の数の検出出力矩形があれば、グループ化して一個とする。double型
   useMeanShiftGrouping = false ---- 上記のグループ化処理、デフォルトで可
で、戻り値はない。
 上記は、重みの出力がない場合である。ある場合には、引数に、foundWeightsの出力が追加される。


図1 HOGDescriptorとSVMを使うプログラム


detectMultiScaleをデフォルトで使用した結果
 まずは、detectMultiScaleをデフォルトにして、三種類の条件を比較した。「D-D-D」などの表示は、図2に示した各出力ウィンドウのタイトルに対応している。図の左は、people.pngで、比較的単純な背景に、ほぼ同じサイズの人が居る。右はzagreb.pngで、人と紛らわしい背景に、大小入り混じった人が居る。
 「D-D-D」とは、HOGDescriptorに対してDefault、setSMVDetectorに対してgetDefaultPeopleDetector、detectMultiScaleに対してDefaultの意味である。「L」はdaimLerを、「U」はUserSpecifiedを意味する。
 1)D-D-D
  HOGDescriptorをデフォルトでコンストラクトし、デフォルトのgetDefaultPeopleDetector()のデータを用いた。
  左のpeople.pngでは、人を全く検出でず、右のzagreb.pngでは一人のみであった(図2の上段参照)。
 2)L-L-D
  HOGDescriptorを、Daimler用にコンストラクトし(検出ウィンドウを48 x 96にする)、getDaimlerPeopleDetector()を用いた。
  検出できた人の数は増えたが、ウィンドウサイズが大きすぎたり、誤検出が多かった(図2の中段参照)。
 3)U-D-D
  HOGDescriptorで、検出ウィンドウサイズをデフォルトの1/2の32 x 64にし、その他のウィンドウも比例して1/2にし、デフォルトのgetDefaultPeopleDetector()のデータを用いた。
  左の画像については、まだ検出数が不足しているが、右では、ほぼ良好な結果で(図2の下段参照)、以後、これを出発点にして、細かくチューニングすることにした。




図2 detectMultiScaleがデフォルトの場合、ユーザー設定のwinSize(32, 64)が良かった


detectMultiScaleでwinStrideをデフォルト以外に減らして使用した結果
 まずは、detectMultiScaleで、winStrideをデフォルトのSize(4, 4)からSize(2, 2)とSize(1, 1)に減らして、それぞれの結果を比較した。「0-4-2」などの表示は、図3の各出力ウィンドウのタイトルに対応している。
 「0-4-2」とは、detectMultiScaleにおいて、hitThreshold = 0、winStride = Size(4, 4)、finalThreshold = 2を意味する。
 1)0-4-2(デフォルトであり、図2の下段と同じ)
  左のpeople.pngの場合、人を検出できるが、全てではない(図3の上段参照)。
 2)0-2-2
  人の検出数が少し増えたが、右のzagreb.pngでは誤検出が発生した(図3の中段参照)。
 3)0-1-2
  人の検出数がさらに増えたが、右のzagreb.pngでは誤検出がさらに増えた(図3の下段参照)、以後、これを出発点にして、改善することにした。




図3 detectMultiScaleの設定では、winStride = Size(1, 1)が良い


detectMultiScaleでhitThresholdとfinalThresholdをデフォルト以外にした結果
 detectMultiScaleで、winStrideをSize(1, 1)に設定し、hitThresholdとfinalThresholdを変化させて結果を比較した。図4での「HT=-0.4, FT=4」などの表示は、hitThreshold = -0.4、finalThreshold = 4を意味する。
 1)HT=-0.4, FT=4
  左のpeople.pngに対して最も良い条件で、右のzagreb.pngに対しては、検出条件が甘すぎた。(図4の上段参照)。
 2)HT=0.4, FT=2
  右のzagreb.pngに対して最も良い条件で、左のpeople.pngに対しては、検出条件が厳しすぎた。(図4の下段参照)。



図4 上は、左のpeople.pngの最適条件、下は、右のzagreb.pngの最適条件


結 論
 ここで使用した画像サイズと被探索対象の人のサイズに関する限り、HOGDescriptorに設定する検出ウィンドウサイズは、デフォルトの64 x 128よりも、その1/2の32 x 64が良かった。
 detectMultiScaleでは、検出ウィンドウの移動ステップwinStrideを、デフォルトでなく、最小のSiae(1, 1)にするのが良かった。ただし、時間がかかる欠点がある。
 detectMultiScaleのその他の引数であるhitThresholdは、デフォルトの0でも使用できるが、少しマイナスにして感度を上げたり、正の値で条件を厳しくしたりして、若干改善された。groupThresholdは、デフォルトの2でも良いが、誤検出が多い場合には増やすと良い。
 すべての被検出画像に対して、共通の最適設定条件はなく、場合による調整が必要である。
 HOGDescriptorで検出ウィンドウのサイズを32 x 64と小さくしたため、それに比例して、セルサイズも4 x 4になった。標準の8 x 8を使用しないで問題はないのか、公開資料では見かけない使い方であるので、心配な面もある。冒険なのか、暴挙なのか、でも、結果オーライではある。

参考文献
 P. Viola, M. J. Jones and D. Snow, "Detecting Pedestrians Using Patterns of Motion and Appearance"(2005)
 http://www.merl.com/publications/docs/TR2003-90.pdf

 N.Dalal and B.Triggs, "Histogram of Oriented Gradientsfor Human Detector"(2005)
 http://lear.inrialpes.fr/people/triggs/pubs/Delal-cvpr05.pdf

 M. Bertozzi, A. Broggi, M. DEl Rose, M. Felisa, A. Rakotomamonjy and F. Suard, "A Pedestrian Detector Using Histogras of Oriented Gradients ans a Support Vector Machine Classifier"(2007)
 http://asi.insa-rouen.fr/enseignants/~arakoto/publi/its2007.pdf

 S. Walk, N. Majer, K. Schindler and B. Schiele, "New Features and Insights for Pedestrian Detection"(2010)
 http://www.igp.ethz.ch/photogrammetry/publications/pdf_folder/walk10cvpr.pdf

   P. Dollar, C. Wojek, B. Schiele and P. Perona, "Pedestrian Detection: An Evaluation of the State of the Art"(2012)
 http://vision.ucsd.edu/~pdollar/files/papers/DollarPAMI12peds.pdf

 S. Rujikietgumjorn and R. T. Collins, "Optimized Pedestrian Detection for Multiple and Occluded People"(2013)
 http://vision.cse.psu.edu/publications/pdfs/cvpr2013SitapaCollins.pdf



「Visual C++の勉強部屋」(目次)へ