2013年2月5日火曜日

Kinectのキャリブレーション with libfreenect その1

Kinectのアプリを作成しようとして詰まったことのメモ類

環境は以下の通り。

Ubuntu 12.10 + libfreenect

有名な話ではあるが、HW構成上Kinectはその奥行き画像とRGB画像を取得するカメラが別々のため、取得した情報がずれている。
これを解決するためには両方のカメラから取得した画像の同じ場所を指し示すピクセルを重ねるキャリブレーションの処理が必要となる。
キャリブレーションの方法は以下のページで見つけることができた。

Robot No.8080のブログ
  http://blog.goo.ne.jp/roboz80/e/64560d75b580ec7359dc23cd0a25e9ef

 Nicolas Burrus Homepage
   http://nicolas.burrus.name/index.php/Research/KinectCalibration

ただ、何が起こっているのかいまいち良く分からなかったので下記を参考に読み解いた。

詳解OpenCV
http://www.oreilly.co.jp/books/9784873114132/

詳しくてわかりやすくておすすめです。

まずは11章カメラモデルの基本から
次のようなピンホールカメラを考える



ピンホール平面の中心に穴が開いており画像平面に結像させるというものである。
ピンホール平面の中心は投影中心とも言われ、各々の方向から1本の光線しか通さないと仮定すれば(穴が十分に小さければ)画像平面、すなわち撮像素子やフィルムを置く平面での写す物体の大きさはその構成から求まる焦点距離のみによって決定され、この時常に像は焦点があった状態にある。
その像の大きさは相似図形から求める事ができる。

    -y =  f ( Y/ Z)

画像平面を物体側に持ってくると座標は-1倍されて次のような図になる。
(後のため、見やすくするためと本には書いてあるが、確かに見やすい)


結果として実際の世界の物体の距離を(X,Y,Z)とした場合、画像平面状への写像は(x,y)となり、
その関係は次の式で表されることとなる。

  x = f (X / Z)
  y = f (Y / Z)

ただし、これは画像平面の中心が光軸と一致している場合の話で、実際にはここに誤差が生じる。
すなわち x = xscreen + cx, y = yscreen + cyとなる。これを上の式に当てはめると次の通り。

  xscreen = f ( X / Z ) + cx
  yscreen = f ( Y / Z ) + cy

実際にはxscreen, yscreenはピクセル単位なので、
fは焦点距離で本ではfx,fyと分けられているが、
これは焦点距離の話をしてから導入する。

うーん、ほとんど本の内容を咀嚼した結果だが、
こういうのはブログじゃないほうがいいのかな。よくわからん。
問題あれば削除しますので誰か教えてください。




0 件のコメント:

コメントを投稿