意外と簡単に出来た。
こないだは繋いでデモを動かしてみただけだったのですが、自分で何かするためには、自分でちゃんとビルドできてキモである距離画像を取得したいところ。それで、サンプルコードを読んでみた。
使っているのは以下のドライバなので、それについてきた Kinect-MinimalSample.cpp を見る。
こいつがやってるのは
- Kinect を探す
- Kinect のインスタンスを作る
- Listener のインスタンスを作成し、Kinect のインスタンスに登録する
- モーターを動かして、正面を向かせる
- 黄色のLEDを点灯させる
- 加速度の値を取得する
- キー入力を待って後片付け(Listener を開放して LED を OFF)
ということ。Kinect には加速度センサも載ってたんですね。モーターは下向きが0、正面が1の間で、首を縦に振れるらしい。1を設定すると、加速度センサの値も見て、水平な正面を向くような感じ。分解能は知らない。LEDは7つのパターンで光らせることができるようだ。
どうやら、Listener が登録されると自動的に画像の取得も開始されているらしいので、その画像を取得してみる。
まずその前に、必要最小限なプロジェクト構成を確認してみた。Kinect-MinimalSample のビルドのために、新規に作成したプロジェクトに追加したファイルは以下のもの。include のパスは適宜変えてくだされ。リンクに必要なものは libusb.lib。
- Kinect-MinimalSample.cpp
- Kinect-Driver.cpp
- Kinect-win32.cpp
- Kinect-FrameInput.cpp
- Kinect-win32.h
- kinect-win32-internal.h
- init.h
- usb.h
さて、後はキー入力待ちになる前にループを作って画像を取得してみた。
まずは確認が簡単なカラー画像。これは、mColorBuffer の指している先の画像がVGAサイズのRGB画像だった。各チャンネル1バイトの3チャンネル。メモリの内容をそのまま取得して OpenCV の IplImage に渡してみたら、色はおかしいが上下は正しい向きだった。これは Windows の OpenCV が BGR 並びであることが原因なので、並びを直してやれば問題なし。
次に、距離画像の取得。こちらは mDepthBuffer が指している。11ビット(0-2047)の値が入るので unsigned short の配列で VGA サイズの数だけ受けてあげれば良い。グレースケールで表示できればいいかと思って 8bit に落としてみたらあまりいい見栄えではないので、Kinect-Demo.exe のソースを参考に白黒グラデのリピートにしてみた。
テレビを斜めに横切る白と黒の境界線は、Kinect からある一定の距離にある面との交線なわけです。
カラー画像と距離画像は撮影範囲が一致しているわけではないので、キャリブレーションが必要なようです。調べていたら以下のページがありました。
距離画像の値をメートルに直す式も載ってました。