コンピュータービジョンの粒子フィルターアルゴリズム:ステレオビジョン

粒子フィルターアルゴリズムは、そのシンプルさと直感性で注目に値します。 左右のカメラからの2つの画像の「同じポイント」を比較するために、立体視のタスクで使用する独自のバージョンを提供します。 実装(娯楽目的のみ)のために、Pythonはnumpy(マトリックスコンピューティング)およびpygame(グラフィックスおよびマウスイベント処理)ライブラリとともに使用されました。 パーティクルフィルターアルゴリズム自体は、変更なしで、Udacityのロボット車プログラミングコースから取得されます。 私の唯一の言い訳は、コース全体を正直に聞いて、このアルゴリズムの実装を含むすべての宿題をしたことです。



立体視のタスクでは、左右のフレームの小さな領域(たとえば、8x8ピクセル)を比較する必要があります。 カメラを厳密に水平方向に理想的に配置し、左右のフレーム間の同じ領域のX軸上の座標の違いを把握して、この領域に表示されるオブジェクトまでの距離を計算できます。 紛らわしいように聞こえますが、実際には、類似の三角形の規則に従って最も単純な幾何学的構造によって簡単に推測されます。 たとえば、未完成の鐘楼のあるビデオでは、同じ菱形で遠くに行くフェンスが見えます。 私たちに最も近い菱形は、左に比べて右フレームで最も強くシフトし、次の菱形はわずかに小さくなります。



この問題を解決するための標準的なスキームは、計算上非常に困難です。 左フレームのY座標を持つ水平線が、右フレームの同じ座標の水平線と正確に一致するように、カメラの相対位置の誤差を較正する必要があります。 次に、左フレームの水平線に沿った各ポイント(または領域)を右フレームの最適ポイントと一致させます(これは、たとえば、2次の複雑さを持つ動的計画法によって解決されます)。 次に、問題の水平に沿った各ポイントのOxに沿った変位を計算します。 そして、各水平線に対して手順を繰り返します。 少し複雑で、脳内でどのように機能するのかはまったく違います(わかっていますよね?)







パーティクルフィルターアルゴリズムが同じ問題をどのように解決するかをご覧ください。 私の意見では、これは生物学的モデルに非常に似ており、少なくともマイクロアイの動きは画像の個々の断片に注意を向けるためにシミュレートされ、そのようなマイクロ動きの「背景」が考慮されます。







粒子フィルターアルゴリズム自体は非常に単純です。 N個のポイントを生成し、それらをパーティクルと呼びます。 粒子は、元の仮説の周りの平面にランダムに配置されます。



ステレオビジョンタスクの詳細
ステレオビジョンの問題では、ガウス分布、特に1000個の粒子を使用しました。 左側のフレームは、左側のカメラからの画像です。 左フレームの任意のポイントをマウスでクリックすることにより、フォーカスをシミュレートします。 ビデオでは、左のフレームに緑色の長方形が表示されます。 これを「注目の焦点」と呼びます。 同時に、これは最初の仮説、つまり 左フレームの焦点は、右フレームのほぼ同じ座標の領域に対応すると考えられます。



この点の座標は、粒子分布の中心になります。 パーティクルクラウドは右フレームに生成されます。 ビデオには2つの右フレームがあります。 下部(黒と白)は粒子の雲全体を示しています。 上部(カラーフレーム)には、最も「正しい」10個のパーティクルのみが表示されます。 以下の適切なパーティクルミツバチを参照してください。





次に、各粒子について、それがどの程度「正しい」かを確認します。 正確であればあるほど、重みが大きくなります(重みの行列、つまりベクトルを構成していることは誰もが理解していることです)。



ステレオビジョンタスクの詳細
タスク内の各粒子の正確さ(つまり、重量)は、左フレームの注目の焦点との類似性の尺度です。 私たちの写真の粒子は正しいフレームにあることを思い出させてください。 私たちが持っている粒子は、調査エリアの黒と白のピクセル輝度値の8x8マトリックスです。 私は愚かにも別の8x8行列(つまり、右から左、またはその逆)を減算し、差の二乗の合計を計算します。 数値が小さいほど、左右の画像は同じになります。



注意! これは、画像の2つの領域を比較する非常に原始的な方法です。 より良い方法があります。たとえば、減算する前に、局所コントラストの正規化を行います。 色を考慮して改善を開始しますが、今はそれを無視して、すべてをグレーの濃淡で検討します。





今、私たちは仮説を動かしています。 パーティクルフィルターアルゴリズムでは、仮説をどこに移動させるかを少なくとも大まかに知る必要があります。



ステレオビジョンタスクの詳細
モデリングプログラムでは、注意の焦点を移動したい左フレームでマウスを手動でクリックするだけです。 たとえば、私はフェンスに沿って動いています(ビデオのように)。 アルゴリズムの各ステップで、1つのフォーカス移動が考慮されることに注意してください。



以前のフォーカスと新しいフォーカスの座標がわかっている場合、変位ベクトルを取得します(たとえば、左に19ピクセル、下に2ピクセル)。





これでアルゴリズムの核になりました。 古いパーティクルから新しいパーティクルクラウドを作成しています。 この場合、2つのアクションを実行します。重みに比例して「古い」パーティクルを選択し、仮説が移動した同じベクトルに移動します。



つまり、「古い」パーティクルの重量が大きいほど、新しいクラウドに移動する可能性が高くなります。 ニュアンスがもう1つあります。新しいパーティクルを移動するとき、変位ベクトルにカオスエラーが必ず追加されます。



ステレオビジョンタスクの詳細
したがって、古い粒子のセットから1000個の新しい粒子を選択します。確率は古い粒子の重量に比例します。 明らかに、この場合、新しい粒子の雲には、左フレームの注目の焦点の領域に最も類似した右フレームの領域があります。



選択したパーティクルについて、フォーカス変位ベクトルとランダム値(中心が0のガウス)を追加することにより、平面上の座標を変更します。



これらの粒子を右下のフレームに描いています。





それだけです サイクル



次に、クラウド全体から最大の重みを持つ10個のパーティクルを選択します(右上のフレームに表示します)。 それらの中心の平均値は、右側のフレームに注目する焦点の座標と見なされます。 つまり、対応する領域が左右のフレームにあります! 座標の差を計算し、それを式(カメラ間の距離とレンズの焦点距離も含む)に代入し、Z座標(カメラから注意の焦点までの距離)を取得できます。



いくつかの焦点を移動した後、粒子の雲が減少するので、ビデオを見てください。 最初は、アルゴリズムは「現在地」を認識しませんが、2〜3回の反復の後、クラウドは収縮し、背景を考慮して注意の焦点を追跡します。 これは、アルゴリズムの大きな利点です。 たとえば、標準的なステレオビジョンアルゴリズムの場合、一連の水平方向の繰り返し要素はほとんど乗り越えられない障害です。 ビデオでは、これは繰り返し菱形のフェンスです。 アルゴリズムが背景を記憶しているという事実により、それは自信を持って菱形を互いに区別します。



作業の結果、ウィンドウの左下隅に白い点のある黒いボックスができました。 上からの投影に表示されるポイントがあります。 見てください:0秒から9秒まで、私たちは精神的にフェンスに沿って移動し、画面の下端に平行に白い点が表示されます。つまり、上からフェンスを見ることに対応しています。



次に、13秒から32秒まで、フェンスが私たちから遠ざかるのを見ていきます。 上からの投影上の点は、この状況を正しく反映しています。 その後、フェンスに沿ってパスに沿って走り続け、白い点がパスの計画を描きます(砂の中にはベビーカーの痕跡がありますが、低解像度のビデオではほとんど見えません)。



最後に、鐘楼に目を向けると、粒子の雲が突然「失われた」、つまり、焦点の動きが大きすぎて、画像間の明示的な対応を明らかにすることができなかったことがわかります。 しかし、文字通り3〜4回の繰り返しで、雲は再び縮小し、自信を持って鐘楼の輪郭と窓を追跡します。 同時に、カメラの解像度は左右のフレーム間の座標の差を表示するのに十分ではないため、ベルタワーまでの距離Zは無限になります。 フレームの解像度は非常に低く、230x344のみであることに注意してください。







このビデオでは、アルゴリズムは別の画像でテストされています。 0〜20秒で墓石をどれだけ自信を持って処理できるかを確認してください。 次に、ブッシュとブッシュ自体からシャドウの輪郭を正常に描画します。投影では、シャドウが投影するシャドウの中央部分に正しく収まることに注意してください。 そして、再び私たちは背景に移され、粒子の雲で失われますが、すぐに復元され、自信を持って同じ壁の破片を見つけます。 しかし、彼らはすでに私たちから無限に遠く離れています...



更新



ソースコードpastebin.com/a8hDiyMc



要件:





コードの品質を判断しないでください、それはあなた自身の娯楽のために書かれました。



All Articles