memorandums

日々のメモです。

Kinectセンサーの深度計測に関する実験

■2012/8/9追記
Kinectの仕組みに関するわかりやすく詳細な解説がトランジスタ技術2012年8月号にあります。興味のある方はそちらを入手してくださいね.

画像処理はもとより3次元計測などはまったくの素人ですが、違う領域を勉強するのはいい刺激になります。とりあえずKinectセンサーの製造元であるPRIME SENSEの特許を読みました。

Link:Depth mapping using projected patterns

Link:THREE-DIMENSIONAL SENSING USING SPECKLE PATTERNS

そもそも基礎知識がないので最初は何がいいたいのか良くわかりませんでしたが、何度か読んでいるうちに少しずつわかってきました。ただ、勘違いがあるかもしれません。。。

何となくではありますが、理解したのは以下のような感じです。特許の図を使います。

赤外光のドットパターンが30から対象(図では手)に向けて投光され、そのイメージを38で受光します。投光部と受光部の距離はS、Kinectと対象の距離がZOBJです。ここで手がZ軸方向に移動すると対象に投影されているドットはX軸方向に移動します(投光部と受光部がX軸に沿って設置されているため)。この対象のZ方向の移動量とドットのX方向の移動量は三角測量の要領で以下の関係になります。

で、特許にあるフローチャートを示します。

最初にキャリブレーションして深度の初期値を得ます(50、52、54)*1。その後、フレームごとに赤外線イメージを取得し(56)、上記の関係式よりδXからδZを求めるようです。δZしか計算できないとすると絶対深度はわからないはずですが。。。積分するとは書かれていないようなのでどうやって最終的に深度を決定しているのかまだわかりません。とりあえず深度の計算方法はおいておいて。

δXに話しを戻しますが。δXを決めるにはドットに注目するはずですが、特許によるとそうではなく小領域(窓)ごとに行うようです。小領域のサイズについては特許内で言及されています。ドットサイズ(要はKinectセンサーと対象の距離に応じて変化する量)に応じて小領域のサイズを決定するようです。小領域のマッチングにはimage correlationなどを使うと書かれています。こちらによるとimage correlationは面積相関法であるようです。で、せっかくなので計算を簡略化したSSDA法でマッチングできるかプログラムを作って実験してみました。かなり荒っぽいですがきちんと動いてしまったのはちょっと驚きです。

帰りの電車でお試しで作ったので汚い&わかりにくくてすいません。とりあえず説明しますと、こちらを押して起動します。起動後には時間がかかるかもしれません。ドットパターンが表示されたら起動成功です。起動後、ウィンドウ内をクリックしてみてください。するとマウスカーソルの位置に黄色い線が表示されるはずです。これはクリックした位置から右方向に10ドットの領域と画像全領域をSSDAで比較し、もっとも差が小さい領域に黄色い線を書くプログラムとなっています。当たり前といえば当たり前なのですが、画像中に同じようなパターンがありそうに見えるのですが、最も近い領域が必ずクリックした位置になるのです。ちなみにこの画像は特許(PDF)から切り抜いたもので、特許の説明によるとX軸方向に対して無相関になるようなパターンなのだそうです。確かにこのパターンであればランダムに見えるドットパターンに対して一意に場所を特定できることになります。

Link: image correlation

じゃ、一意に決定できるといっても際どいんじゃないかな。。。と思ったわけです。そこで全領域に対してSSDAで差を求めた結果についてグラフを書かせてみました。以下です。ちょっとわかりにくいですが50000の右に1点だけ相関値が0のデータがあると思います。この点にマッチしたことになります。

オリジナルパターンと比較しているだけですので、ノイズや欠落のない最も理想的な状態でのマッチング結果になります。

*1:ここが良くわからないのですが、何らかの方法で対象の絶対深度?を計測すると思われます。