1.はじめに
小型のRGB-Dセンサとして昨今話題のIntel Real Sense、サンプルも豊富で色々と遊べるのですが、自分でプログラムを書こうとするとサンプルもリファレンスも初学者には少々分かりにくい印象を受けました。そこで今回、カラー画像とdepth画像を取得して表示するというだけの簡単なサンプルをC#用に作成しました。
内輪向けに作成したものですが、誰かの参考になればと思ったので公開します。今回は開発手順に従って説明をするため多少回りくどくなるかもしれません。まずコード全体を見たいという方はこちらからソースをダウンロードしてください。
なお、本記事ではプロジェクトへのライブラリの追加等は完了しているものとして話を進めます。ライブラリの設定等については、公式ドキュメント(Intel® RealSense™ SDK Documentation)のConfiguring C# Development Environmentを参考にしてください。
2.開発手順
まずデザイナ画面上でフォーム上にPictureBoxを2つ横並びに配置します。また、PictureBoxのサイズはそれぞれ640×480とします。
続いて、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(); } }
ここまで書けたらプログラムを実行してみましょう。下の写真のようにランプが点灯したらセンサの接続までが完了です。
次は画像の取得と描画を行います。まずは、キャプチャと表示を行う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行を追加したら出来上がりです。
private void Form1_FormClosing(object sender,FormClosingEventArgs e) { //下記を追加 running = false; thread.Abort(); }