openCV と python で SLAMする

さて、夏休みも終わりですね。
世間の皆様方は旅行行ったり海に行ったりとリア充ライフを満喫されたでしょうか?

私はこれといって特別なことはせずに、ネットみたり本読んだりとフツーの日々を過ごしていました。
夏は冷房の効いた部屋で過ごすに限りますからね。

といってもただ怠惰に過ごしていたわけでもなくブログのネタを仕込んだり、資格試験の勉強したりと それなりに有意義に過ごせたと思います。

で、本題ですが、タイトルにもある通りSLAMをやりたいと思います。

SLAMとはもちろん不良たちがバスケをやって成長していく有名マンガではなく、Simultenious Localizetion And Mapping の略称です。

SLAMについてもう少し付け加えると、これは自動運転車やお掃除ロボットが自分の位置を把握するために用いる技術で、
センサ値から自己位置推定と周囲の地図作成を平行して行うというものです。
大抵はセンサとしてレーザーレンジファインダを用いるのですが、カメラを使ったものもあり、Visual-SLAMと呼ばれます。 (Visual Odometryとも)

今回はこのVisual-SLAM(以下VSLAM)を実装していこうと思います。

今回実装するVSLAMについて

今回はwebカメラを用いた単眼VSLAMを実装しようと思います。
フローとしてはだいたい以下のような形になると思われます。

  1. カメラのキャリブレーションを行い、キャリブレーション行列を求めておく
  2. 画像を撮る(このときの視点を視点1とする)
  3. 移動して視点を変える
  4. 画像を撮る(このときの視点を視点2とする)
  5. 2,4で撮影した画像間で共通する特徴点を抽出する
  6. (a) 特徴点の対応から視点1から視点2への移動を計算する(回転行列、平行移動ベクトルを求める)
    (b) 特徴点の三次元座標を計算する
  7. 特徴点の三次元座標、視点1,2の画像,画像上での特徴点座標,各視点でのカメラ姿勢、位置を記録する
  8. バンドル調整を行う
  9. 2へ戻る

各処理について簡単に説明すると

1のキャリブレーションはレンズの歪みを補正するための処理です。単眼でなく複眼のVSLAMを行う場合はカメラごとに行う必要があると考えられます。

2~4では撮影と移動を行っています。

5では特徴点を検出しています。ロバスト性を強めたいので今回はSURF特徴量を用います。検出にはopenCVのモジュールを用います。

6で視点間の相対位置と三次元座標の計算を行っています。視点の移動をもとに三次元構造を把握するこの手法はSfM(Structure from Motion)と呼ばれます。

7ではマップの構築と記録を行っています。本当ならステップ5のあとで検出した特徴点をDBに問い合わせ、既出のものか判断する必要があります。

8ではバンドル調整なる処理を行います。位置推定と地図作製をそのまま繰り返すと誤差が蓄積するため、それを除去する処理です

さて、大枠としては上記のようになります(なると思います)。 次回以降キャリブレーションについてサンプルプログラムと一緒に見ていきたいと思います。

参考図書

  • 実践コンピュータビジョン

実践 コンピュータビジョン

実践 コンピュータビジョン

この書籍はコンピュータビジョンの入門として買ったのですが、ソースコードpythonで書かれておりとても読みやすかったです。 今回実装するVSLAMでは主にこのpythonコードとopenCVを使って実装しようと考えています。