KinectのデータからOpenGLで立体表示する(その2)

前回の反省

  • 前回、KinectのデータからOpenGLで立体表示するでOpenGLを使ったkinectのデータの表示を行ったが、いくつか間違いと改善点があった。
    1. 色のデータの順が、RGBではなく、BGRだった件。
    2. カラーデータが、左下から右上に入っていると思っていたのが、右下から左上だった件
    3. 連続データの描写方法が分からなかった件
  • これらを今回解決した。

ヒスイを使った3D動画描写

  • 前回、いまいちうまくいかなくて、静止画で諦めていたのだが、今回、ヒスイの開発者のid:u_1rohさんのアドバイスのおかげでできるようになった。
    • とても便利なフレームワークの開発無償公開に加えて、今回の助言を心から感謝します。

Kinectのほう

  • 描写の方法としては、まず、前回作った、kinectのデータを取ってくるプログラムの中で、Hisuiを使ったフォーム(今回は、HisuiTestというワークスペース内)をhisuiとか適当な変数名でインスタンス化。
  • ボタンをクリックすることで以下を呼ぶ。
hisui.Visible = true;
HisuiTest.Class1.setMainWindow(this);
HisuiTest.Class1.DrawPoints();
  • setMainWindowとDrawPointsの説明は後でする。
  • 加えて、後にHisuiTestのDraw関数からポイントをリクエストできるように、以下の関数を作る。
public void getPoint(HisuiTest.Point[] pt, HisuiTest.RGB[] pc)
{
	//ptとpcにはそれぞれ参照渡しでピクセル毎の深度データ、RGBデータをいれる。
}

HisuiTest内

  • PointとRGBを格納するクラスをそれぞれ作成
public class Point
{
    public float x, y, z;
    public Point(float _x, float _y, float _z)
    {
        x = _x;
        y = _y;
        z = _z;
    }
}

public class RGB
{
    public float r, g, b;
    public RGB(float _r, float _g, float _b)
    {
        r = _r;
        g = _g;
        b = _b;
    }
}
  • そして、メインフレームから送られてきたアドレスを保管し、draw関数を呼ぶstaticのクラスを作る。
public class Class1
{
    static private WpfApplication1.MainWindow mw;
    static public void setMainWindow(WpfApplication1.MainWindow _mw)
    {
        mw = _mw;
    }

    static public void DrawPoints(Hisui.Ctrl.IContext con)
    {
        con.View.SceneGraph.WorldScenes.Add(new PointScene(mw));
    }
}
  • で、あとはシーンを作成
public class PointScene : Hisui.Graphics.IScene
{
    Point[] pt;
    RGB[] pc;
    float size = 1.0f;
    WpfApplication1.MainWindow mw;

    public PointScene(WpfApplication1.MainWindow _mw)
    {
        mw = _mw;
    }

    public void Draw(Hisui.Graphics.ISceneContext sc)
    {
        //Kinect からデータ取得
        mw.getPoint(pt, pc);

        //点群を描画
        using (var scope = sc.Push())
        {
            scope.Lighting = false;
            GL.glPointSize(size);
            GL.glBegin(GL.GL_POINTS);
            for (int i = 0; i < pt.Length; i++)
            {
                GL.glColor3d(pc[i].b, pc[i].g, pc[i].r);
                GL.glVertex3d(pt[i].x, pt[i].y, pt[i].z);
            }
            GL.glEnd();
        }
        //描画が終わる度に次の描画のリクエストを発行する
        Hisui.SI.View.Invalidate();
    }
}

デモ

  • へたくそな英語ですが説明付きのデモ動画は以下

  • こんな感じで、綺麗に動きました!
  • まだまだ他の人のには及ばないけど満足
  • 発展で何ができるか考え中。