読者です 読者をやめる 読者になる 読者になる

tks_yoshinagaの日記

KinectやLeap motion, VRやARなどの技術を使ってやったことのメモとか

Intel Real Sense用サンプル for C# Formアプリケーション

試作

1.はじめに

 小型のRGB-Dセンサとして昨今話題のIntel Real Sense、サンプルも豊富で色々と遊べるのですが、自分でプログラムを書こうとするとサンプルもリファレンスも初学者には少々分かりにくい印象を受けました。そこで今回、カラー画像とdepth画像を取得して表示するというだけの簡単なサンプルをC#用に作成しました。

 内輪向けに作成したものですが、誰かの参考になればと思ったので公開します。今回は開発手順に従って説明をするため多少回りくどくなるかもしれません。まずコード全体を見たいという方はこちらからソースをダウンロードしてください。
 なお、本記事ではプロジェクトへのライブラリの追加等は完了しているものとして話を進めます。ライブラリの設定等については、公式ドキュメント(Intel® RealSense™ SDK Documentation)のConfiguring C# Development Environmentを参考にしてください。

2.開発手順

まずデザイナ画面上でフォーム上にPictureBoxを2つ横並びに配置します。また、PictureBoxのサイズはそれぞれ640×480とします。
f:id:tks_yoshinaga:20150305193709p:plain

続いて、Form1.csのソースコードを表示しPXCMSenseManagerの変数smの宣言と、InitializeSensor関数の記述を行います。さらに、InitializeSensor関数をForm1()コンストラクタで呼び出します。

public partial class Form1 : Form
{
     //センサマネージャ
     PXCMSenseManager sm; 

     public Form1()
     {
          InitializeComponent();
          //RealSenseを初期化
          InitializeSensor();
      }
      //センサ(RealSense)の初期化
      private void InitializeSensor()
      {
           sm = PXCMSenseManager.CreateInstance();
           //カラー画像の使用を有効化(640*480,30fps)
           sm.EnableStream(
              PXCMCapture.StreamType.STREAM_TYPE_COLOR, 
              640, 480, 30);
           //depth画像の使用を有効化(640*480,30fps)
           sm.EnableStream(
              PXCMCapture.StreamType.STREAM_TYPE_DEPTH, 
              640, 480, 30);
           //センサマネージャを初期化
           sm.Init();
       }
}


ここまで書けたらプログラムを実行してみましょう。下の写真のようにランプが点灯したらセンサの接続までが完了です。
f:id:tks_yoshinaga:20150305201514j:plain


次は画像の取得と描画を行います。まずは、キャプチャと表示を行うDoRendering()関数をForm1クラス内に記述します。

//キャプチャ終了条件。キャプチャ中はtrue
bool running=false;

//キャプチャおよび表示
private void DoRendering()
{
     //runningがtrueの間、常に画像取得と描画が繰り返される。
     while (running)
     {
     //カラー・デプス画像が来るまでブロック
         if (sm.AcquireFrame(true) 
              < pxcmStatus.PXCM_STATUS_NO_ERROR) break;
         //センサが取ってきた情報をを取得
         PXCMCapture.Sample sample = sm.QuerySample();
         //カラー画像を取得
         PXCMImage image = sample.color;
         //デプス画像を取得
         PXCMImage image2 = sample.depth;
         
         PXCMImage.ImageData data;
         PXCMImage.ImageData data2;

         //dataを介してカラー画像のピクセルデータにアクセス
         image.AcquireAccess(PXCMImage.Access.ACCESS_READ, 
             PXCMImage.PixelFormat.PIXEL_FORMAT_RGB32, out data);
         //data2を介してdepth画像のピクセルデータにアクセス
         image2.AcquireAccess(PXCMImage.Access.ACCESS_READ, 
             PXCMImage.PixelFormat.PIXEL_FORMAT_RGB32, out data2);
         
         //data,data2をbitmapに変換後、各pictureboxに渡す
         pictureBox1.Image = data.ToBitmap(0, 640, 480);
         pictureBox2.Image = data2.ToBitmap(0, 640, 480);

         //解放
         image.ReleaseAccess(data);
         image2.ReleaseAccess(data2);
         sm.ReleaseFrame();
     }
     //runningがfalseになったら解放
     sm.Dispose();
}

更に下記の(追加)と書かれているコメントの下のコードを書き加えることで、RealSenseの初期化終了後に描画処理が別スレッドで実行されるようになります。

public partial class Form1 : Form
{
     PXCMSenseManager sm; 
     bool running=false;

     //キャプチャ&描画スレッド(追加)
     System.Threading.Thread thread;
     
     public Form1()
     {
          InitializeComponent();
          InitializeSensor();
          //別スレッドでDoRenderingを実行(追加)
          thread = new System.Threading.Thread(DoRendering);
          thread.Start();
          //描画フラグをtrue(追加)
          running = true;
      }

      //センサ(RealSense)の初期化
      private void InitializeSensor()
      {
           /*省略*/
      }

      //キャプチャおよび表示
      private void DoRendering()
      {
           /*省略*/
      }
}


 再びデザイナに戻り、プロパティのイベント一覧の中から[FormClosing]を見つけ、その右側の空欄をダブルクリックすることでウィンドウ終了時の処理を行う関数を追加します。最後に、コードエディタに戻り、Form1_FormClosing関数に下記の2行を追加したら出来上がりです。

f:id:tks_yoshinaga:20150305205137j:plain

private void Form1_FormClosing(object sender,FormClosingEventArgs e)
{
     //下記を追加
     running = false;
     thread.Abort();
}

3.終わりに

 RealSenseのようなモーションセンサを用いたアプリ開発には、Unityやprocessingなどが主流になりつつあるかと思いますが、C#でも何か作ってみたいという方の参考になれば幸いです。
 加えて、本記事でReal Senseの接続から画像表示までの流れを把握し、そのうえで公式サンプルのRaw Streamsを読むと更に理解が進むのではないかと思います。
f:id:tks_yoshinaga:20150306072138p:plain

3月7日追記:
IntelのDeveloper ZoneにC#/WPFでのサンプルが掲載されていることがわかりました。かなりスッキリ書かれているのでおススメです。