KinectのデータからOpenGLで立体表示する
きっかけ
- まだWindows SDK for Kinectが公開される前、Kinect Hackの一例としてとても有名になった3D Video Capture with Kinect みたいな事をやってみたいと思った。
方法
- C#でOpenGLするフリーのFramework「ヒスイ」を使ってやってみることに。
- 理由は、以下紹介文より
気軽にOpenGLアプリを作りたい。その場合、有名なのはGLUTです。
でも、GLUTでは Projection Matrix の設定やマウスによるビューの回転操作など、全て自分で作り込まなくてはなりません。 ヒスイは完成されたビューを持っているため、Projection Matrix やマウス操作を自分で作る必要はありません。 だからといってプログラマから自由を奪うことはなく、OpenGLのコードを自由にシーン中に埋め込むことが出来ます。 また、ポリゴンのデータ構造も持っていますので、ポリゴンのデータを扱うのにも便利です。
ヒスイは C# により .NET Framework 上に構築されています。つまり、.NET Framework のパワーをフルに活かした 本格的なアプリケーションの開発にも使用することが出来ます。GLUTは本格的なアプリケーションには向きませんが、 ヒスイならばそれが可能です。
ヒスイは、GLUT以上の気軽さで、より本格的なOpenGLアプリケーションの開発を支援します。
ヒスイ
- 開発チュートリアルに沿ってセットアップ。とても親切な説明なので、以下の3つを読めば十分理解できる。
Kinectの画像処理
- カメラの復習はKinect for Windows SDK 入門3:カメラ基礎から。
- kinectは32bitビットマップを使ってるため、用意する配列のサイズはWidth×Height×4
- CopyPixelsを使って、BitmapSourceから配列にコピー。
- strideは、単純にWidth×4
bitmapSource.CopyPixels(imageArray, bitmapSource.PixelWidth * bitmapSource.PixelWidth * 4, 0);
- コピーした配列から、OpenGLで利用する新しい配列を作る。
- それぞれのピクセルに対して4ビット。
- 1ビット目にBlue、2ビット目にGreen、3ビット目にRedが0〜255の値で入っている。(4ビット目は0)
- OpenGLではこれを0〜1までの値で扱うため、それぞれの値を求める。
- 気をつけないといけないのは、それぞれのカラービットは左下から右上方向に格納されていること。(詳しくはこちら)
- カメラのイメージは640×480に対して、Kinectの深度データは320×240だったので、一個ずつ飛ばして同じサイズにした。
float[][] color = new float[320 * 240][]; int count = 0; for (int y = 480 - 1; y >= 0; y-=2) { for (int x = 0; x < (640 * 4); x+=8) { int indexFrom = x + (479 - y) * (640 * 4); color[count] = new byte[3]; color[count][0] = data[indexFrom] / 255.0; color[count][1] = data[indexFrom + 1] / 255.0; color[count][2] = data[indexFrom + 2] / 255.0; count++; } }
- 深度データは、x=index%360, y=index/360, z=depth[index]という感じに。
- それでヒスイで表示。
デモ(オリジナルにミスがあったので修正(2011/07/14))
- 元データ
- 3Dデータ
- 違う角度から(1)
- 違う角度から(2)
- 動画はこんな感じ
- いいんだけど、youtubeのやつの劣化版コピーみたいになって残念
改善点
- わざわざカメラのイメージを320×240に縮小する必要なかった。4個ずつ同じ深度に置けば良かった。
- 単純に点を描写するのではなく、triangulateとかしてもうすこし画面をスムーズにした方がいいのかな。要勉強
Kinect関連記事
- Kinect関連記事