Kinectと処理の概要

Microsoft Kinectセンサーは、ウェブカメラのように機能する周辺機器(XBoxおよびwindows Pc用に設計されています)です。 ただし、RGB画像を提供することに加えて、深度マップも提供します。 意味Kinectは、センサーからの距離を測定します。 これは、背景の除去、ブロブ検出、およびより簡単で楽しいようなコンピュータビジョンの問題の様々なものになります!

Kinectセンサー自体は色と深さのみを測定します。 しかし、その情報がコンピュータ上にあると、”スケルトン”追跡(つまり、人のモデルを検出し、彼/彼女の動きを追跡する)のように、より多くのことができます。 スケルトントラッキングを行うには、Thomas Lenglingのwindows専用のKinect v2processing librayを使用する必要があります。 ただし、Macを使用していて、Kinectの生データだけが必要な場合は、運がいいです! このライブラリは、libfreenectとlibfreenect2オープンソースドライバを使用して、Mac OS X用のデータにアクセスします(windowsのサポートは近日公開予定)。

どのようなハードウェアが必要ですか?

まず、”スタンドアロン”kinectが必要です。 Xboxを購入する必要はありません。

  • スタンドアロンKinectセンサー v1。 私はあなたが次に記載されている別のアダプタを必要としないので、これは電源が付属していると信じています。 ただし、XBoxに付属のkinect v1をお持ちの場合は、Kinectセンサーの電源は含まれません。
  • スタンドアロンKinectセンサー v2。 また、おそらくWindows用のKinectアダプタが必要です。 それはwindowsを言うが、これはあなたがUSB経由であなたのmacに接続することができます、オフにスローされないでください。 最後に、お使いのコンピュータがUSB3をサポートしていることを確認することもできます。 最新のマシンはほとんどそうですが、不明な場合は、Mac OS Xの詳細をここで見つけることができます。

異なるモデルに関するいくつかの追加メモ:

  • Kinect1414:これはオリジナルのkinectであり、Processing3.0betaシリーズのこのページに記載されているライブラリで動作します。
  • Kinect1473:これは1414と同じように見えますが、更新されたモデルです。 このライブラリで動作するはずですが、テストするライブラリはありません。 それがそうであるかどうか私に知らせてください!
  • Kinect for Windowsバージョン1:???? 助けて? これは動作しますか?
  • Kinect for Windowsバージョン2:これは、XBox One Kinectのすべての機能を備えた新しいkinectのブランドです。 また、このライブラリで動作します!

SimpleOpenNI

SimpleOpenNIライブラリの使用を検討し、Greg BorensteinのMaking Things See bookを読むこともできます。 OpenNIには機能(スケルトントラッキング、ジェスチャー認識など)があります。 このライブラリでは利用できません。 残念ながら、OpenNIは最近Appleによって購入されましたが、私はそれがシャットダウンされたと思っていましたが、それを復活させるためのいくつかの努力. OpenNIとSimpleOpenNIの将来がどうなるかは不明です。

今すぐ始める準備ができています

ライブラリをインストールする最も簡単な方法は、Processing Contributions Manager Sketch→Import Libraries→Add libraryを使用して”Kinect”を検索することです。 “インストール”というラベルの付いたボタンが表示されます。手動でインストールする場合は、最新のリリースをダウンロードしてlibrariesフォルダーに展開します。 処理を再起動し、examplesフォルダ内の例のいずれかを開くと、あなたは行ってもいいです!

処理とは何ですか?

Processingは、画像、アニメーション、インタラクションを作成したい人のためのオープンソースのプログラミング言語と環境です。 当初はソフトウェアスケッチブックとして機能し、視覚的な文脈の中でコンピュータプログラミングの基礎を教えるために開発され、処理も完成したプロの仕事を生成するためのツールへと進化してきました。 今日では、学習、プロトタイピング、および生産のための処理を使用する学生、アーティスト、デザイナー、研究者、および愛好家の数万人があります。

処理を使用したくない場合はどうすればよいですか?

C++に慣れている場合は、OpenframeworksまたはCinderをKinectで使用することを検討することをお勧めします。 これらの環境にはいくつかの追加機能があり、深度データなどを処理するときにC++の速度の利点が得られることもあります。:

  • Openkinectプロジェクト

どのようなコードを書くのですか?

最初に、コードの先頭に適切なimport文を含めることです:

import org.openkinect.processing.*;

Kinectオブジェクトへの参照だけでなく、

Kinect kinect;

次に、setup()でそのkinectオブジェクトを初期化できます:

void setup() { kinect = new Kinect(this); kinect.initDevice();}

Kinect v2を使用している場合は、代わりにKinect2オブジェクトを使用します。

Kinect2 kinect2;void setup() { kinect2 = new Kinect2(this); kinect2.initDevice();}

これが完了したら、kinectセンサーからデータにアクセスすることができます。 現在、このライブラリは5つの方法でデータを利用できるようにしています:

  • PImage (RGB) kinectビデオカメラから。Kinect IRカメラから
  • PImage (grayscale)
  • PImage (grayscale)各ピクセルの明るさを深さにマッピングします(明るい=近い)。
  • PImage (RGB)各ピクセルの色相を深さにマッピングします。
  • int array生の深度データ(0~2048の11ビット番号)を使用します。

これらを一度に見てみましょう。 あなただけの通常の古いウェブカメラのようなKinectを使用したい場合は、PImageとしてビデオ画像にアクセスすることができます!

PImage img = kinect.getVideoImage();image(img, 0, 0);

ただし、videoEvent()を使用して新しい画像がいつ利用可能かを知ることもできる場合は、draw()でこの画像を求めることができます。

void videoEvent(Kinect k) { // There has been a video event!}

IR画像が必要な場合:

kinect.enableIR(true);

kinect v1では、ビデオ画像とIR画像の両方を取得できません。 それらは両方ともgetVideoImage()を介して返されるので、最も最近有効になったものはどちらかが取得されます。 ただし、Kinect v2では、両方とも別々の方法として利用できます:

PImage video = kinect2.getVideoImage();PImage ir = kinect2.getIrImage();

これで、深度画像が必要な場合は、グレースケール画像を要求できます:

PImage img = kinect.getDepthImage();image(img, 0, 0);

生の深さデータと同様に:

int depth = kinect.getRawDepth();

kinect v1の場合、生の深度の値の範囲は0から2048の間で、kinect v2の場合、範囲は0から4500の間です。

色深度画像にはkinect.enableColorDepth(true);を使用します。 また、ビデオ画像と同様に、必要に応じてアクセスできる深度イベントがあります。

void depthEvent(Kinect k) { // There has been a depth event!}

残念ながら、B/c RGBカメラとIRカメラは物理的に同じ場所に位置していないため、ステレオビジョンの問題があります。 ある画像のピクセルXYは、カメラからの画像のXYと同じではありません。 Kinect v2は、すべての深度値をRGBカメラの値と整列させる”登録済み”画像と呼ばれるものを提供します。 これは次のようにアクセスできます:

PImage img = kinect2.getRegisteredImage()

最後に、kinect v1(ただしv2ではありません)では、setTilt()メソッドでカメラ角度を調整することもできます。

float angle = kinect.getTilt();angle = angle + 1;kinect.setTilt(angle);

だから、あなたはそれを持っている、ここでは、処理kinectライブラリを使用する必要があるかもしれないすべての便利な機能があります:

  • initDevice() — すべてを開始する(ビデオ、深さ、IR)
  • activateDevice(int) – 複数のデバイスが接続されているときに特定のデバイスを有効にする
  • initVideo() — ビデオのみを開始
  • enableIR(boolean) — IRカメラの画像をオンまたはオフにする(v1のみ)
  • initDepth() — 開始深度のみ
  • enableColorDepth(boolean) — カラー画像として深度値をオンまたはオフにします
  • enableMirror(boolean) — 画像と深度データのミラーリング(v1のみ)
  • PImage getVideoImage() — RGB(またはV1の場合はIR)ビデオ画像を取得します
  • PImage getIrImage() — IR画像を取得する(v2のみ)
  • PImage getDepthImage() — 深さマップを取得する 画像
  • PImage getRegisteredImage() — 登録された深度画像を取得する(v2のみ)
  • int getRawDepth() — 生の深度データを取得する
  • float getTilt() — 電流センサーの角度(0~30度)を取得します(v1のみ)
  • setTilt(float) — センサーの角度を0~30度の間で調整します(v1のみ)

他のすべてについては、javadocリファレンスを見ることもできます。

v1とv2の両方には四つの基本的な例があります。

RGB、IR、および深度イメージの表示

v1のコード:RGBDepthTest

v2のコード:Rgbdepthtest2

この例では、上記のすべての関数を使用して、kinectセンサーからのデータを表示します。

複数のデバイス

v1とv2の両方が複数のkinectをサポートしています。

v1のコード:MultiKinect

v2のコード:Multikinect2

点群

v1のコード:PointCloud

v2のコード:PointCloud

ここでは、少し手の込んだことをやっています。 第一に、我々は空間に点を描画するために処理の3D機能を使用しています。 Translate()、rotate()、pushMatrix()、popMatrix()に慣れておく必要があります。 このチュートリアルでは、開始するには良い場所です。 さらに、この例では、PVectorを使用して3D空間内の点を記述します。 詳細はこちら:PVectorチュートリアル。

しかし、この例の実際の仕事は私から来たものではありません。 Kinectからの生の深度値は、物理的な深度に正比例しません。 むしろ、これらは次の式に従って深さの逆数でスケーリングされます:

depthInMeters = 1.0 / (rawDepth * -0.0030711016 + 3.3309495161);

この計算を常に行うのではなく、2048の深さの値しかないため、ルックアップテーブルでこれらの値をすべて事前計算できます。

float depthLookUp = new float;for (int i = 0; i < depthLookUp.length; i++) { depthLookUp = rawDepthToMeters(i);}float rawDepthToMeters(int depthValue) { if (depthValue < 2047) { return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161)); } return 0.0f;}

上記の式のMatthew Fisherに感謝します。 (注:結果をより正確にするには、特定のkinectデバイスを校正する必要がありますが、式は私には十分に近いので、今のところそれに固執しています。 一瞬で校正についての詳細。)

最後に、メートル単位の深さの値に基づいていくつかの点を描くことができます:

 for(int x = 0; x < w; x += skip) { for(int y = 0; y < h; y += skip) { int offset = x + y * kinect.width; // Convert kinect data to world xyz coordinate int rawDepth = depth; PVector v = depthToWorld(x, y, rawDepth); stroke(255); pushMatrix(); // Scale up by 200 float factor = 200; translate(v.x * factor, v.y * factor, factor-v.z * factor); // Draw a point point(0,0); popMatrix(); } }

平均点トラッキング

kinectの本当の魔法は、そのコンピュータビジョン機能にあります。 深さ情報を使用すると、言うような楽しいことのすべての種類を行うことができます:”背景は5フィートを超えて何かです。 無視しろ!”深さがなければ、背景の除去にはあらゆる種類の骨の折れるピクセル比較が必要です。 このアイデアの簡単なデモンストレーションとして、ここでは、指定された深さしきい値の前にある任意のピクセルの平均xy位置を計算する非常に基本

v1のソース:AveragePointTracking

V2のソース: Averagepointtracking2

この例では、2つの変数を宣言して、適切なxとyをすべて加算し、1つの変数を宣言して、いくつの変数があるかを追跡します。

float sumX = 0;float sumY = 0;float count = 0;

次に、しきい値に準拠する特定の点を見つけるたびに、xとyを合計に追加します:

 if (rawDepth < threshold) { sumX += x; sumY += y; count++; }

完了したら、平均を計算してポイントを描きます!

if (count != 0) { float avgX = sumX / count; float avgY = sumY / count; fill(255, 0, 0); ellipse(avgX, avgY, 16, 16);}

何が欠けているのですか?

  • すべてがgithubの問題を介して追跡されています。

よくある質問

  1. 奥行き画像(v1)に影は何がありますか? Kinectシャドウダイアグラム
  2. kinectが見ることができる深さの範囲は何ですか? (v1)~0.7–6メートルか2.3–20フィート。 遠すぎて近すぎる両方の要素で、黒のピクセル(または生の深度値2048)が取得されることに注意してください。

コメントを残す

メールアドレスが公開されることはありません。