![]() |
OpenCV 5.0.0
Open Source Computer Vision
|
前のチュートリアル: 背景差分法の使い方
次のチュートリアル: オプティカルフロー
本章では、
Meanshiftの背後にある考え方は単純である。点の集合があるとする(ヒストグラムのバックプロジェクションのような、ピクセルの分布でもよい)。小さなウィンドウ(円でもよい)が与えられ、そのウィンドウをピクセル密度が最大(または点の数が最大)の領域へ移動させなければならない。これを下の単純な図で示す:
最初のウィンドウは「C1」という名前の青い円で示されている。その元の中心は「C1_o」という名前の青い四角で示されている。しかし、そのウィンドウ内の点の重心を求めると、「C1_r」という点(小さな青い円で示されている)が得られ、これがウィンドウの実際の重心である。当然ながら両者は一致しない。そこで、新しいウィンドウの円が直前の重心に一致するようにウィンドウを移動する。再び新しい重心を求める。ほとんどの場合、一致しない。そこで再び移動し、ウィンドウの中心とその重心が同じ位置に(または小さな所望の誤差の範囲内に)来るまで反復を続ける。こうして最終的に得られるのは、ピクセル分布が最大となるウィンドウである。これは「C2」という名前の緑の円で示されている。図でわかるように、点の数が最大になっている。この一連の処理を、下の静止画像上で示す:
そこで通常は、ヒストグラムをバックプロジェクションした画像と初期の対象位置を渡す。物体が動くと、当然その動きはヒストグラムをバックプロジェクションした画像に反映される。その結果、Meanshiftアルゴリズムはウィンドウを密度が最大となる新しい位置へ移動させる。
OpenCVでMeanshiftを使うには、まず対象を設定し、そのヒストグラムを求めて、各フレーム上で対象をバックプロジェクションしてMeanshiftの計算に使えるようにする必要がある。また、ウィンドウの初期位置も与える必要がある。ヒストグラムについては、ここでは色相 (Hue) のみを考慮する。さらに、低照度による誤った値を避けるため、低照度の値は cv.inRange() 関数を使って除外する。
使用した動画の3フレームを以下に示す:
直前の結果をよく見ただろうか。一つ問題がある。車がカメラから非常に遠くにあっても非常に近くにあっても、ウィンドウのサイズは常に同じである。これはよくない。対象のサイズや回転に応じてウィンドウのサイズを適応させる必要がある。ここでも解決策は「OpenCV Labs」から生まれ、CAMshift (Continuously Adaptive Meanshift) と呼ばれる。これはGary Bradskyが1998年の論文「Computer Vision Face Tracking for Use in a Perceptual User Interface」で発表したものである [41] 。
まずMeanshiftを適用する。Meanshiftが収束したら、ウィンドウのサイズを \(s = 2 \times \sqrt{\frac{M_{00}}{256}}\) として更新する。また、それに最もよく当てはまる楕円の向きも計算する。再び、新しくスケールされた探索ウィンドウと前回のウィンドウ位置でMeanshiftを適用する。必要な精度が満たされるまでこの処理を続ける。
Meanshiftに似ているが、回転矩形(これが結果である)とボックスのパラメータ(次の反復で探索ウィンドウとして渡される)を返す。以下のコードを参照:
結果の3フレームを以下に示す: