本文へスキップ

けいはんなジュニアロボットクラブは、子供たちに「モノづくり」の楽しみと「科学技術」への興味をもってもらう取り組みを行っています。

TEL. 070-5349-1100

〒619-0237 京都府相楽郡精華町光台8丁目

KINECT











【 KINECT 】カラーカメラと深度(距離)カメラを使ってみる。(基本プログラム)


   ここでのプログラムは、Kinect へアクセスし、距離カメラとカラーカメラの両方から画像を読み出し、そしてその2つを並べて画面上に表示します。

プログラム


import SimpleOpenNI.*;
SimpleOpenNI kinect;

void setup()
{
 size(640*2, 480);
 kinect = new SimpleOpenNI(this);

 kinect.enableDepth();
 kinect.enableRGB();
}

void draw()
{
 kinect.update();

 image(kinect.depthImage(), 0, 0);
 image(kinect.rgbImage(), 640, 0);
}



プログラム解説

  • import SimpleOpenNI.*;
    Processing 用のライブラリーのインポート
    このライブラリーは、SimpleOpenNI という名前で、PrimeSense 社(現在はApple社に買収)から提供されてる OpenNI ツールキットの、Processing ラッパーです。
  • SimpleOpenNI kinect;
    SimpleOpenNI オブジェクトを宣言し、それに kinect と名前をつけている。
    ここでは、単に宣言をしただけでインスタンス化はしていない。インスタンス化は setup 関数の中で行います。
  • setup 関数
    void setup()
    {
     size ( 640 * 2, 480 )

    kinect から送られる画像は、幅が 640 ピクセルで高さが 480 ピクセル。
    ここでのサンプルでは、kinect からの2つの画像(距離画像とRGB画像)を横に並べて表示するための設定。

    kinect = new SimpleOpenNI ( this );

    スケッチの最初で宣言した SimpleOpenNI のインスタンスを実際にインスタンス化している部分。

     kinect.enableDepth ( );
     kinect.enableRGB ( );

    インスタンスを手に入れた所で、次にこのインスタンス上の2つのメソッド、enableDepth と enableRGB とを呼んでいる。
  • draw 関数
    draw 関数の中ではまず、kinect オブジェクトの update 関数を呼び出している。

     void draw ( )
     [
      kinect.update( );

    これは、新しいデータを kinect から取得し、取り扱えるようにしてほしいとライブラリーへ伝えている。

    最後の2行が、今回のスケッチの心臓部です。

      image( kinect.depthImage( ), 0, 0 );

    まず kinect.depthImage を呼んで、直近の利用できる距離画像をライブラリーに要求。
    この画像は、次に Processing の組み込み image 関数に、両方ともゼロに設定された別の2つの引数と共に渡されている。
    これは、Processing に、われわれのスケッチの( 0, 0 )つまりアプリのウインドウの左上隅に距離画像を描画させる為のものです。

      image( kinect.rgbImage( ), 640, 0 );

    先ほどの距離画像の時と同じ内容ですが、2点異なる部分が カラー画像の取り込みと 640, 0 という所です。
    カラー画像は、フレームの左端から 640 ピクセル離れた所に配置するという意味になります。


実行結果(実際の作業場所です)




プログラム解説の補足

  上記プログラムの draw 関数部で、
  kinect.depthImage と kinect.rgbImage を、image へ与える引数としてインラインで呼び出していますが、これらの関数が協調して動作している重要な部分を隠蔽して
  しまっている。
  kinect.depthImage や kinect.rgbImage の戻り値を全く見ていない事となっていて、これからアプリを作成していく上では問題となってきます。
  それでは、どの様にすればいいのでしょうか?

   void draw ( )
   {
    kinect.update( );
    
    PImage depthImage = kinect.depthImage( );
    PImage rgbImage  = kinect.rgbImage( );

    image( depthImage, 0,0 );
    image( rgbImage, 640, 0 );
   }

  kinect.depthImage と kinect.rgbImage の戻り値を暗黙に processing の image 関数へ渡す代わりに、ここではローカル変数に一度保存してから、これらの変数を image
  へ渡している。
  これによってスケッチ機能はまったく変わらないし、実行しても振る舞いにはまったく違いは感じられない。
  ここで行っているのは、2つの画像アクセス関数の戻り値の形を明確に指定していることです。
  kinect.depthImage と kinect.rgbImage は両方ともProcessing が画像データの保存に使用するクラス PImage を返す。
  このクラスは、画像の各ピクセルへのアクセスや変更など、画像処理に役立つ各種の関数を提供していて、これからそれらの関数を使ったアプリを作ります。