67
1 Hough Forestを用いた物体検出 http://mprg.jp/tutorials/hough-forest 機械知覚&ロボティクス研究グループ(中部大学)

Hough forestを用いた物体検出

Embed Size (px)

Citation preview

1

Hough Forestを用いた物体検出 http://mprg.jp/tutorials/hough-forest

機械知覚&ロボティクス研究グループ(中部大学)

中部大学工学部 ロボット理工学科

宮腰 あゆみ機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of Engineering

Ayumi Miyakoshi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 ロボット理工学科助手

山内 悠嗣機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-8249Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of EngineeringResearch Assistant

Dr.Eng.Yuji Yamauchi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-8249Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 情報工学科講師

山下 隆義機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9670Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Computer ScienceCollege of EngineeringLecturer

Dr.Eng.Takayoshi Yamashita

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9670Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 ロボット理工学科教授

藤吉 弘亘機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of EngineeringProfessor

Dr.Eng.Hironobu Fujiyoshi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 ロボット理工学科

宮腰 あゆみ機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of Engineering

Ayumi Miyakoshi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 ロボット理工学科助手

山内 悠嗣機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-8249Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of EngineeringResearch Assistant

Dr.Eng.Yuji Yamauchi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-8249Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 情報工学科講師

山下 隆義機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9670Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Computer ScienceCollege of EngineeringLecturer

Dr.Eng.Takayoshi Yamashita

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9670Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

中部大学工学部 ロボット理工学科教授

藤吉 弘亘機械知覚&ロボティクスグループ487-8501愛知県春日井市松本町1200Tel 0568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

博士(工学)

MACHINE PERCEPTION AND ROBOTICS GROUP

Chubu UniversityDepartment of Robotics Science and TechnologyCollege of EngineeringProfessor

Dr.Eng.Hironobu Fujiyoshi

Machine Perception and Robotics Group1200 Matsumoto-cho, Kasugai, Aichi487-8501 JapanTel +81-568-51-9096Fax [email protected]://vision.cs.chubu.ac.jp

MACHINE PERCEPTION AND ROBOTICS GROUP

Hough Forestを用いた物体検出

1. 前処理 ‒ 学習用画像の生成

2. Hough Forestの学習 ‒ 学習用画像の入力, パッチの切り出し ‒ 決定木の構築

3. Hough Forestによる検出 ‒ テスト画像の入力 – 決定木を用いた投票処理

‒ 検出ウィンドウの統合

4.ソースコード詳細

2

前処理

• Hough Forestを用いて物体検出を行うために学習画像を生成する ‒ 物体を検出する際に想定される姿勢の画像を準備する必要あり

3

アルゴリズム解説

• ダウンロード先 ‒ URL : http://vision.cs.chubu.ac.jp/MPRG/SRC/HoughForest/makeRotateImage.zip

• 作成環境 ‒ Visual Studio Ver. 2010, C++ ,OpenCV2.4.3

ソースコード

4

フォルダ構造

• 学習画像生成プログラムのフォルダ構造

5

フォルダ構造

makeRotateImage.sln

makeRotateImage/ image/

dst/

src/

makeRotateImage/ inPos/

inNeg/

outPos/

outNeg/

入力画像の配置先

出力画像の保存先

• 1枚の物体画像から学習用画像を生成 – 入力画像を回転して切り出し – プログラム:makeRotateImage

• 物体の重心が画像の中心になるよう撮影された画像を入力 • 360度回転し切り出した画像を出力

– 入力画像からトリミングするため出力画像は縮小 – 回転角度は変更可能(デフォルトでは10度刻みで回転)

学習用画像の生成

6

・・・

入力画像生成される学習用画像

0度 10度 20度 360度

0.bmp 1.bmp 2.bmp 35.bmp画像中心

アルゴリズム解説

36枚

学習用画像の生成

• 入力画像:指定したフォルダ内に配置 ‒ 物体重心が画像の中心になるよう撮影 ‒ 入力する画像の枚数に合わせてIMG_NUMを変更

• 入力画像名は0始まりの連番 例: 0.jpg 1.jpg … 9.jpg 10.jpg • 画像の形式によってIMAGE_TYPEを変更(デフォルトは jpg)

• 出力画像:指定したフォルダ内に連番で書き出し ‒ ANGLE_STEPで指定したずらし幅でANGLEで指定した度数まで回転 ‒ 画像形式はpngで固定

7

プログラム解説

共通設定(1/5)

1. ダウンロードしたソリューション(.sln)を開く

‒ VS2010にてプログラムを作成しているためVS2013の場合ソリューションのアップデートが始まります

• 完了したら次へ

8

作業手順の解説

注意:今回はVS2010(64bit版)を対象

共通設定(2/5)

2. OpenCVを使用するためパスを通す ‒ メニューバーのプロジェクトから「プロパティ」を開く

‒ 構成プロパティを一度クリック

9

作業手順の解説

共通設定(3/5)

‒ 構成(C):「アクティブ」から「すべての構成」に変更

‒ 「C/C++」の全般の「追加のインクルードディレクトリ」に使用するOpenCVのincludeフォルダを指定

10

作業手順の解説

共通設定(4/5)

‒ 「リンカー」の全般の「追加のライブラリディレクトリ」に使用するOpenCVのlibフォルダを指定

‒ 2013の場合 opencv2.49/build/x64/vc12/libで動作します

11

作業手順の解説

‒ includeCV.h内で必要なライブラリを読み込んでいるので ライブラリのリンクを設定する必要は無し

• ただしopencvのバージョンを変更した場合「249」をバージョンに合わせて変更して下さい

共通設定(5/5)

12

作業手順の解説

前準備:作業手順

1. 入力画像を指定のフォルダに配置 ‒ 指定フォルダ:inPos/, inNeg/

• 今回はあらかじめ配置されております

2. パラメータの設定 ‒ 設定の必要があるパラメータ

‒ 今回はデフォルトのままでOK

3. 実行 ‒ 出力保存先フォルダoutPos/, outNeg/にそれぞれ 連番画像が生成されていれば実行完了 13

作業手順の解説

#define POS_IMG_NUM 1 //ポジティブ画像枚数

#define NEG_IMG_NUM 2 //ネガティブ画像枚数

#define ANGLE 360 //回転角度

#define ANGLE_STEP 10 //回転角のずらし幅

#define RESIZE 400 //切り出し後の画像サイズ

Hough Forestを用いた物体検出

1. 前処理 ‒ 学習用画像の生成

2. Hough Forestの学習 ‒ 学習用画像の入力, パッチの切り出し ‒ 決定木の構築

3. Hough Forestによる検出 ‒ テスト画像の入力 – 決定木を用いた投票処理

‒ 検出ウィンドウの統合

4.ソースコード詳細

14

Hough Forestの学習

1. 学習用画像の入力とパッチ画像の作成 ‒ 特徴量の算出: HOG特徴量

2. 決定木の構築 ‒ 分岐関数の設計 ‒ 末端ノードの作成

15

アルゴリズム解説

ソースコード

• ダウンロード先 ‒ URL : http://vision.cs.chubu.ac.jp/MPRG/SRC/HoughForest/HoughForest.zip

• 作成環境 ‒ Visual Studio Ver. 2010, C++ ,OpenCV2.4.3

• プログラムの構成 ‒ 学習, 認識のプログラムが統合

• common.h #define MODEを1に設定で学習プログラムが動作

16

フォルダ構造

• HoughForestの学習プログラムのフォルダ構造

17

フォルダ構造

src/

入力画像の配置先

学習結果の保存先

HoughForest/ HoughForest/

HoughForest.sln

forest/

Learning_sample/ learning_images/ Pos/

Nos/

result/

Test_sample/ test_images/

• 入力された学習用画像からパッチを作成 ‒ 指定したサンプリング幅でパッチを切り出し ‒ ポジティブパッチのみ物体重心までのオフセットベクトルを算出

学習用画像の入力とパッチ画像の作成

18

アルゴリズム解説

重心

オフセットベクトルポジティブ画像

ネガティブ画像

なし なし なし

切り出し

ポジティブパッチ

ネガティブパッチ

・・・

・・・

オフセットベクトル

• 生成した学習用画像の読み込み ‒ 使用関数:LearningImage() ‒ 入力:前準備で生成した学習画像を指定フォルダに配置

• パッチ画像の作成 ‒ 使用関数:extractPatch()

学習用画像の入力とパッチ画像の作成

19

学習用画像の入力とパッチ画像の作成のため設定するパラメータ#define LEARNING_IMAGE_PATH “./Learning_sample/learning_images/“ //学習画像のパス//指定したパス以下のフォルダ Pos/ 内にポジティブ画像, Neg/ 内にネガティブ画像を置いてください

#define NEG_NUM 36 //ネガティブ画像の枚数#define POS_NUM 36 //ポジティブ画像の枚数#define SCALE .25 //画像スケール係数//学習画像が大きい場合 1.0以下 学習画像が小さい場合 1.0以上(係数を小さくするとパッチが切り出せない場合があります)

#define WINDOW_WIDTH 32 //パッチの縦サイズ(偶数に設定) #define WINDOW_HEIGHT 32 //パッチの横サイズ(偶数に設定)

特徴量の算出

20

• 使用する特徴量 ‒ Histograms of Oriented Gradients[Dalal, CVPR ’05] ‒ 局所領域におけるエッジ(勾配)の方向をヒストグラム化した特徴量 

エッジ方向の方向ヒストグラム

アルゴリズム解説

メリット:明るさの変化などの影響を受けにくい     形状の変化に頑健

21

HOG特徴量の算出アルゴリズム

1. 輝度の勾配方向と勾配強度の算出 2. ヒストグラムの作成 3. 閾値処理と正規化

アルゴリズム解説

1. 輝度の勾配方向と強度の算出

2. ヒストグラムの作成 ‒ 0°から180°までを、20°ずつ9方向に分割

22

HOGの算出法(1/2)

�fx(x, y) = L(x + 1, y)� L(x� 1, y)fy(x, y) = L(x, y + 1)� L(x, y � 1)

m(x, y) =�

fx(x, y)2 + fy(x, y)2

�(x, y) = tan�1 fy(x, y)fx(x, y)

勾配強度:

勾配方向:(x, y) (x+ 1, y)

(x� 1, y)

(x, y � 1)

(x, y + 1)

アルゴリズム解説

3. 閾値処理と正規化 ‒ あるn番目のHOG特徴量について正規化

• 背景から算出される小さな勾配は閾値処理で除外

‒ 32×32の入力画像 • 1セル:8×8ピクセル、1ブロック:1×1セル

23

HOGの算出法(2/2)

(1)×(4×4)× 18 = 228個(次元)のHOG特徴量

正規化回数 セル数 勾配方向数

アルゴリズム解説

v(n) =

8<

:0 :

qPNk=1 v(k)

2< th

v(n)pPNk=1 v(k)2

: otherwise

今回はブロックの正規化なし

N:勾配方向数th:閾値

特徴量の算出

• パッチ画像からHOG特徴量の算出 ‒ 使用関数:CompHist()

• この関数はパッチが切り出されるたびに呼び出されInit関数によって初期化を行う

24

HOG特徴量の算出のために設定するパラメータ#define WIDTH_SELLNUM 4 //分割数(HOG特徴量算出時の横のセル数)#define HEIGHT_SELLNUM 4 //分割数(HOG特徴量算出時の縦のセル数)#define BLOCK WIDTH_SELLNUM * HEIGHT_SELLNUM //ブロック数#define ORIENTATION 18 //勾配パターン数

HOG特徴量の可視化

パッチ画像

HOG特徴量

プログラム解説

決定木の構築

• 作成した学習データを使ってHough Forestsを学習 • 作成する木の数だけサブセットを生成 ‒ サブセット用いて決定木を構築 ‒ サンプルは分岐関数にしたがって分岐

25

サブセットを用いて決定木を構築

・・・

サブセット1

Tree1

サブセット2

Tree2

サブセットT

TreeT

分岐ノード

末端ノード

アルゴリズム解説

決定木の構築

• サブセットの作成 ‒ 使用関数:splitPatch()

• サンプルの重複, 未使用を許容しつつPER_SUBSETで設定した割合でサブセットをNUM_TREESの数だけ作成

• 決定木の構築 ‒ 使用関数:Learn()

• 設定したパラメータで決定木を構築する起点になる関数 ‒ build関数を再帰的に呼び出し決定木を構築

26

決定木の構築のために設定するパラメータ#define NUM_TREES 10 //木の本数#define MAX_DEPTH 60 //木の深さ#define PER_SUBSET 1.0 //サブセットの割合

プログラム解説

分岐関数の設計

• 分岐関数はパッチが持つHOG特徴量と閾値を比較 ‒ HOG特徴量がしきい値以下の場合は左, それ以外は右に分岐

27

パッチの持つHOG特徴量 > Th

右に分岐分岐ノード

アルゴリズム解説

分岐関数の決定方法

• 評価関数の値が最小の候補を分岐関数に決定

• 2つの評価関数を階層とサンプル数に応じて選択 ‒ クラスラベルのエントロピー

‒ オフセットベクトルの分散の値

28

数式

S(v) =

!left i ∈ In|fj(vi) < tjright otherwise

(1)

S(v) =

!Il i ∈ In|fj(vi) < tjIr In\Il

(2)

∆E (3)

Il = i ∈ In|fj(vi) < tj (4)

Ir = In\Il (5)

∆E = E(In) − |Il||In|

E(Il) −|Ir||In|

E(Ir) (6)

E(I) = −N"

n=1

Pnlog2Pn (7)

p(C = P |S) =1T

T"

t=1

SPt

SPt + SN

t

(8)

U1(A) = |A|(−c · logc − (1 − c) · log(1 − c)) (9)

U2(A) ="

i:ci=1

(di − dA)2 (10)

argmink

(U⋆({pi|tk(Ii) = 0) + U⋆({pi|tk(Ii) = 0)) (11)

1

数式

S(v) =

!left i ∈ In|fj(vi) < tjright otherwise

(1)

S(v) =

!Il i ∈ In|fj(vi) < tjIr In\Il

(2)

∆E (3)

Il = i ∈ In|fj(vi) < tj (4)

Ir = In\Il (5)

∆E = E(In) − |Il||In|

E(Il) −|Ir||In|

E(Ir) (6)

E(I) = −N"

n=1

Pnlog2Pn (7)

p(C = P |S) =1T

T"

t=1

SPt

SPt + SN

t

(8)

U1(A) = |A|(−c · logc − (1 − c) · log(1 − c)) (9)

U2(A) ="

i:ci=1

(di − dA)2 (10)

argmink

(U⋆({pi|tk(Ii) = 0) + U⋆({pi|tk(Ii) = 0)) (11)

1

A : パッチ集合c : Aのポジティブクラスの確率

tk : k番目の分岐関数の候補

FLAB Work Document April 26, 2013 6

Hough ImageV 歩行者検出結果

図 6: 投票処理を用いた歩行者検出

ここで dAはオフセットベクトル diの平均値であるので,U2はオフセットベクトルの分散に相当する.2つの評価関数を用いて,各ノードの分岐関数は以下の手順で選択される.まず,式(2)の分岐関数のプール {tk}を生成する.そして,式 (10)を用いて背景パッチと物体パッチの不確実性が最小となる分岐関数を選択する.

argmink

(U⋆({pi|tk(Ii) = 0) + U⋆({pi|tk(Ii) = 0)) (10)

ここで,⋆は 1か 2のいずれかをランダムに選択することを表している.しかし,入力されるパッチ集合に含まれる背景パッチの数があまりに少ない場合,オフセットの不確実性が最小となるように分岐関数を選択するため ⋆には 2が適用される.また,⋆に 1と 2を交互に選択することで,末端ノードでは確実に双方の不確実性が減少していると考えられる.このように構築した木を用いてオブジェクトの検出を行う.識別HFによる物体検出では,入力画像に含まれる対象オブジェクトを投票処理により,重心を求めることでオブジェクトを検出することができる.第 1段階により検出された歩行者候補領域から抽出したパッチを各決定木に入力する.末端ノードに到達した,画像中のある位置 yのパッチ I(y)が画像中の異なる位置 xを中心としたオブジェクトに含まれる確率を式 (11)により算出して,木の本数 T で平均する.

p(E(x)|I(y); {Tt}Tt=1) =

1T

!p(E(x)|I(y); Tt) (11)

次に,異なるパッチからの投票を統合するため,図 6に示すように 2次元のHough ImageV に投票を行う.そして,式 (12)により近隣のパッチからの投票をピクセル位置 xごとに総和すると,図 6(a)に示すようになる.

V (x) =!

p(E(x)|I(y); {Tt}Tt=1) (12)

投票した結果から,mean shift等を用いて算出した極大値をその位置をオブジェクトの重心として図 6(b)のように歩行者を検出することができる.

: パッチ画像

dA : Aのオフセットベクトルの平均

pi :サンプル集合

argmink

(U�({pi|tk(Ii) = 0}) + U�({pi|tk(Ii) = 1}))左の子ノードに分岐したサンプル集合

右の子ノードに分岐したサンプル集合

アルゴリズム解説

分岐関数の設計, 決定方法

• 分岐関数を候補の中から選択 ‒ 使用関数:selectsplitfunctionGrad()

• 分岐の評価が最も良かった分岐のパラメータを保存 ‒ 選択した特徴次元 ‒ 選択した閾値

• 決定した分岐関数を使用しサンプルを分岐 ‒ 使用関数:splitSamplesGrad()

• 現在のノードで分岐したサンプルを左右の子ノードに受け渡し

29

分岐関数の設計, 決定方法のために設定するパラメータ#define TH_TESTS 10 //閾値選択回数 //#define SPLIT_SELECT_MIN 30 //分岐関数を選択する条件//ノードに到達したサンプルが設定した数値以下なら, 評価に分散を使用

プログラム解説

• 木の深さが条件を満たした場合末端ノードを作成 ‒ 作成条件1:木の深さが設定した最大の深さに達する ‒ 作成条件2:ノードのサンプル数が設定した数以下になる

• 末端ノードに到達したサンプルの情報を保存 ‒ ボルトのクラス尤度とオフセットベクトル

末端ノードの作成

30ボルトのクラス尤度オフセットベクトル

保存される情報

深さ

分岐ノード

末端ノード

指定した深さ

指定られた最大の深さでなくとも最小サンプル数以下ならば末端ノードを作成

アルゴリズム解説

末端ノードの作成

• 条件を満たしたとき末端ノードを作成 ‒ 使用関数:selectsplitunctionGrad()

• 作成条件を満たした場合ノードに末端ノードのフラグを立て保持しているサンプルの情報を保存

31

末端ノード作成のために設定するパラメータ#define SAMPLE_MIN 5 //末端ノード作成する条件//ノードに到達したサンプルが設定した数値以下なら, 末端ノードを作成

プログラム解説

Hough Forestの学習:作業手順

1. 生成した学習用画像を指定した入力フォルダコピー ‒ 指定フォルダ:learning_images/Pos/, learning_images/Neg

2. パラメータの設定 ‒ #define MODE 1 になっていることを確認

• 1でない場合は学習プログラムが動きません ‒ SAMPLING_WSTEP, SAMPLING_HSTEPをそれぞれ 2 に設定 ‒ その他パラメータは解きたい問題によって変更

• 今回はデフォルトのまま

3. 実行 ‒ 学習が終了すると作成した木構造がforest/に保存 ‒ 検出時はこのフォルダから作成した木構造を読み込む

32

作業手順の解説

Hough Forestを用いた物体検出

1. 前処理 ‒ 学習用画像の生成

2. Hough Forestの学習 ‒ 学習用画像の入力, パッチの切り出し ‒ 決定木の構築

3. Hough Forestによる検出 ‒ テスト画像の入力 – 決定木を用いた投票処理

‒ 検出ウィンドウの統合

4.ソースコード詳細

33

Hough Forestによる検出

1. テスト画像の入力 2.決定木を用いた投票処理 ‒ 決定木の走査

3.検出ウィンドウの統合 – MeanShiftクラスタリング – Nearest Neighbor

34

ソースコード

• 学習と同一のものを使用

• プログラムの構成 ‒ 学習, 認識のプログラムが統合

• common.h #define MODEを0に設定で検出プログラムが動作

35

フォルダ構造

• HoughForestの検出プログラムのフォルダ構造

36

フォルダ構造

src/

入力画像の配置先

学習結果の読み込み先

HoughForest/ HoughForest/

HoughForest.sln

forest/

Learning_sample/ learning_images/ Pos/

Nos/

result/

Test_sample/ test_images/

検出結果の保存先

• テスト画像をラスタスキャン ‒ 画像中のどこに物体が存在するか探索 ‒ 画像中を網羅的に走査

• それぞれ検出ウィンドウ領域の情報を決定木に入力

テスト画像の入力

37

テスト画像をラスタスキャン

検出ウィンドウ

アルゴリズム解説

テスト画像の入力

• 検出テストを行うためボルトをランダムに配置したテスト画像を入力 ‒ 使用関数:testImage

38

テスト画像の入力のための設定パラメータ#define TEST_IMAGE_PATH "./Test_sample/test_images/" //テスト画像のファイルパス//画像の名前は0から始まる連番にしてください//例 11枚のテスト画像があるとき 0.bmp, 1.bmp, ~9.bmp, 10.bmp#define TEST_NUM 3 //テスト画像枚数

• 探索ウィンドウから特徴量の抽出 ‒ HOG特徴量の算出

• 決定木に入力 ‒ 到達した末端ノードのオフセットベクトルを投票マップに投票

決定木を用いた投票処理

39

ボルトの尤度オフセットベクトル 投票マップ

HOG特徴量を算出し入力

投票

決定木の走査

入力画像

アルゴリズム解説

• 各ノードに保存されている分岐関数の情報をもとに決定木を走査 ‒ 決定木の走査は作成した木の数だけ行う

決定木の走査

40

分岐ノード

末端ノード

検出ウィンドウをすべての決定木に入力

・・・

Tree1 Tree2 TreeT

クラスの尤度オフセットベクトル

クラスの尤度オフセットベクトル

クラスの尤度オフセットベクトル

到達した末端ノードの情報

アルゴリズム解説

決定木の走査,投票処理

• 再帰的に決定木を走査 ‒ 使用関数:Traversal()

• ノードの分岐条件をもとに決定木をたどり末端ノードの情報を返す

• 末端ノードの情報を統合し一つの投票マップに統合 ‒ 使用関数:makeMap()

• Traversal関数により到達した末端ノードの情報を統合 • 統合後viewMap関数に投票マップを渡し画像として描写 • 閾値より小さい投票値は削除(後のクラスタリング処理のため)

41

木の走査のための設定パラメータ#define LIKELIHOOD_TH 0.6 //尤度の閾値//閾値以下の投票は削除

プログラム解説

42

検出ウィンドウの統合

• 一つのボルトに対して複数のウィンドウが検出 – MeanShiftクラスタリングにより点の密度が極値となる点へ移動 – Nearest Neighborにより検出ウィンドウを統合

ウィンドウ統合前 ウィンドウ統合後

アルゴリズム解説

MeanShiftクラスタリング

• x方向、y方向、scaleの3次元でのクラスタリング ‒ ボルトとして判定された検出ウィンドウの中心座標 からMeanShift Vectorを算出

– ウィンドウの半径hの範囲を探索

43

MeanShift Vector:

カーネル関数:

m(x) =

n⌅

i=1

xik⇥���

���x� xi

h

������2⇤

n⌅

i=1

k⇥���

���x� xi

h

������2⇤ � x

アルゴリズム解説

MeanShiftによる効果

• MeanShiftクラスタリングにより投票密度が高い座標に物体重心座標を移動

44

クラスタリング後クラスタリング前

アルゴリズム解説

h = 64

MeanShiftによる効果

• 探索ウィンドウの半径hによってMeanShiftの結果は変化

45

クラスタリング前 クラスタリング後

アルゴリズム解説

h = 10 h = 20

MeanShiftクラスタリング

• 複数検出された物体重心座標をクラスタリング ‒ 使用関数:meanShift()

• 探索範囲内の密度が高い方へ物体重心座標を移動 • 物体重心座標をクラスタごとにまとめることでNearestNeighborにより同一クラスタを統合

46

MeanShiftクラスタリングのための設定パラメータ#define RADIUS 64 //探索範囲の半径

プログラム解説

• 各サンプル点の座標上の距離を観測し 最も近いサンプル点を探索

– クラスタリングされた検出ウィンドウの中心座標を点に統合

• 距離dが閾値thを下回ればサンプル点を統合

47

d =�

(x� xi)2 + (y � yi)2ユークリッド距離:

Nearest Neighbor(最近傍決定則) アルゴリズム解説

Nearest Neighbor(最近傍決定則)

• Meanshiftによりクラスタリングされた 検出ウィンドウの中心座標を統合 ‒ 使用関数:NearestNeighbor()

• 距離の閾値以上 ‒ 別のクラスタと判定し検出ウィンドウを残す

• 距離の閾値以下 ‒ 同一クラスタと判定し検出ウィンドウを統合

48

Nearest Neighborのための設定パラメータ#define WIN_TH 80 //ウィンドウ統合閾値//閾値以上だと別の検出対象として保存 以下だと統合

プログラム解説

Hough Forestによる検出:作業手順

1. テスト画像を指定のフォルダに配置 ‒ 指定フォルダ:test_images/

2. パラメータの設定 ‒ #define MODE 0 になっていることを確認

• 0の場合検出プログラムが動作 ‒ 検出時は学習時と同じパラメータを使用

• SAMPLING_WSTEP, SAMPLING_HSTEPはそれぞれ 1 に設定 ‒ 検出のみに使用するパラメータは変更可

• 今回はデフォルト

3. 実行 ‒ 検出処理が終了するとresult/に検出結果の画像と投票マップが出力

49

作業手順の解説

検出例

50

投票マップ

出力画像

最終的に検出した物体重心点 探索範囲 : h = 64

検出処理時間

• 画像1枚の実行時間(490×490画素):7217.78msec ‒ 内訳

• ラスタスキャン+特徴算出:4574.32 msec • 投票処理:2586.09 msec • 投票マップの正規化:15.04 msec • MeanShift:12.94 msec • NearestNeighbor:18.41 msec • 検出結果の書き出し:10.98msec

‒ 1検出ウィンドウ毎の実行時間 • ラスタスキャン+特徴算出:0.02msec • 投票処理:0.01msec

51

• 本プログラムは物体位置のみ検出 ‒ 物体がどのように置かれているか姿勢も推定したい場合

‒ 学習データの教師情報に物体の姿勢を追加 ‒ x軸, y軸, 角度の3次元マップに確率を投票

改良のためのヒント1

52

360°

:投票点

x軸y軸

3次元MeanShiftクラスタリングθ軸

改良のためのヒント2

• weighted Hough Forest ‒ 決定木を階層毎にサンプルの重みを更新しながら学習

• 階層が深くなる毎に特徴的なサンプルの重みが上昇

53

重み更新

階層

1

0

2

D

重み(ポジティブ) 重み(ネガティブ)

クラス 尤度算出

重み更新 クラス 尤度算出

Murai et al., “Weighted Hough Forest for object detection”, MVA 2015

改良のためのヒント2

• weighted Hough Forestの効果 ‒ 類似した形状のサンプルへの誤投票を抑制

54

Hough Forest

Weighted Hough Forest

検出対象

Murai et al., “Weighted Hough Forest for object detection”, MVA 2015

Hough Forestを用いた物体検出

1. 前処理 ‒ 学習用画像の生成

2. Hough Forestの学習 ‒ 学習用画像の入力, パッチの切り出し ‒ 決定木の構築

3. Hough Forestによる検出 ‒ テスト画像の入力 – 決定木を用いた投票処理

‒ 検出ウィンドウの統合

4.ソースコード詳細

55

Hough Forest:ソースファイル

• プログラム構成(.cpp) – main.cpp (学習・識別のメイン関数) – HoughForests.cpp (HFの生成に関する処理関数) – Decisiontree.cpp (決定木の生成に関する処理関数) – Detector.cpp (物体検出時に使用する処理関数) – ImportSample.cpp (サンプルの入力に関する処理関数) – makeSubset.cpp(パッチの切り出し, サブセットの作成に関する処理関数)

– HoG.cpp (パッチからHOG特徴量を算出する処理関数) – node.cpp (Nodeに関するデフォルトコンストラクタ) – sample.cpp (サンプル情報の入出力に関する関数)

56

Hough Forest:ソースファイル

• プログラム構成(.h) ‒ common.h (学習時, 識別時のパラメータを定義するヘッダ) ‒ HoughForests.h(学習時の決定木のパラメータに関するヘッダ)

– Decisiontree.h (決定木の生成に関するヘッダ) ‒ Detector.h (識別時の決定木のパラメータに関するヘッダ) – ImportSample.h (サンプルの入力に関するクラス) – makeSubset.h (サブセット作成に関するクラス) – HoG.h (HoG特徴量に関するクラス) ‒ node.h (各ノードの情報を格納するクラス) ‒ sample.h (各パッチの情報を格納するクラス) ‒ includeCV.h (OpneCVのライブラリを読み込むヘッダ)

57

Hough Forest:データ構造

• サンプル ‒ 特徴ベクトル

• cv::Mat patch;(パッチ画像の輝度値) • std::vector<std::vector<double>> DOP;(エッジの勾配情報)

‒ 教師信号 • int label;(パッチのクラス情報) • cv::Point offset;(パッチのオフセットベクトル)

‒ オフセットベクトルを持つのはポジティブパッチのみ

58

Hough Forest:データ構造

• ノード – int grad; //勾配方向 ‒ int block; //ブロックインデックス – double t; //threshold – int depth; //depth – int index; //node index – bool nodeType; //true:splitnode false:leafnode – vector<double> distribution;//distribution histogram – vector<Point> offsetList; //node offset List – Node *right; //right node – Node *left; //left node

59

Hough Forest:プログラム概要

60

学習過程:Forestに必要な関数

61

Learn - Forestsを生成するための関数 - 引数:なし - サンプルの読み込みに必要な関数を呼び出し - Decisiontree の Learn を呼び出し Initilizer - Forests の 情報を初期化するための関数 - 引数:Forests のパラメータ - Decisiontree の Initilizer を呼び出し Save - Forests を保存する関数 - 引数:保存するファイル名 - Decisiontree のSaveを呼び出し

HoughForests.cpp

学習過程:サンプルの読み込みに必要な関数

62

learningImage - 学習時に用いる画像を読み込む関数 - 戻り値:ポジティブ画像, ネガティブ画像

ImportSample.cpp

extractPatch - 読み込んだ画像からパッチ画像を生成する関数 - ポジティブパッチに対してオフテットベクトルを取得 - 引数:ポジティブ画像, ネガティブ画像 - HOG特徴量算出に必要な関数を呼び出し splitPatch - サブセットを作成する関数 - 引数:木の数, 全パッチ数に対するサブセットの割合

makeSubset.cpp

CompHist - パッチ画像からHOG特徴量を算出する関数 - 引数:パッチ画像

HoG.cpp

学習過程:Treeの作成に必要な関数

63

Learn - 再帰でノードを生成する関数 - 引数:学習用サンプル, ラベルに対する重み - selectsplitfunctionGrad, splitSamplesGradを呼び出し

Decisiontree.cpp

selectsplitfunctionGrad - 分岐関数を候補の中から選択する関数 - 引数:ルートノードのアドレス, 学習用サンプル, ラベルに対する重み, ノードの深さ,ノード番号 - selectsplitfunctionGrad, splitSamplesGradを呼び出し - ノードを末端ノードと判定した場合クラス確率とオフセット量を保存

splitSamplesGrad - 分岐関数を用いてサンプルを分岐する関数 - 引数:ノードに到達したサンプル - selectsplitfunctionGrad, splitSamplesGradを呼び出し

識別過程:物体検出に必要な関数

64

computeError - Forestsを走査するための関数 - 引数:なし - testimage, loadNode, viewDetection, makeMapを呼び出し

Detector.cpp

loadNode - 再帰でForestsを読み込む関数 - 引数:ファイル名

Traversal - 再帰により決定木を走査する関数 - 引数:ルートノードのアドレス, パッチ画像 - 末端ノードのオフセット量を返す

viewMap - 尤度マップの可視化する関数 - 引数:尤度マップ,未知入力画像の番号 - 尤度マップの閾値処理,正規化処理を行う

識別過程:物体検出に必要な関数

65

meanShift - クラスタリングのための関数 - 引数:尤度マップ

Detector.cpp

NearestNeighbor - 検出統合する関数 - 引数:クラスタリング後の尤度マップ - 閾値により検出ウィンドウを統合するかを判定

makeMap - 末端ノードのオフセット量を尤度マップに投票する関数 - 引数:未知入力画像の番号 - extractPatch,Traversal, viewMap, meanShift, NearestNeighborを呼び出し

viewDetection - 物体位置を描写するための関数 - 引数:検出した物体位置

識別過程:サンプルの読み込みに必要な関数

66

testImage - 識別時に用いる画像を読み込む関数 - 戻り値:評価用画像

ImportSample.cpp

extractPatch - 読み込んだ画像からパッチ画像を生成する関数 - 引数:未知入力画像 - HOG特徴量算出に必要な関数を呼び出し

makeSubset.cpp

CompHist - パッチ画像からHOG特徴量を算出する関数 - 引数:パッチ画像

HoG.cpp

67