2011年6月19日日曜日

Creating an empty project that uses OpenNI

Visual Studioを使った方法です。

1.新しいプロジェクトか、OpenNIを使用したい既存のプロジェクトを開きます。

2.メニューから、「プロジェクト」-「プロパティ」を開きます。

3.C/C++セクションの「全般」で、「追加のインクルードディレクトリ」に、以下を追加します。
$(OPEN_NI_INCLUDE)
これは、OpenNIのインクルードディレクトリの場所を指す環境変数です。
(デフォルトは、C:\Program Files\OpenNI\Include です。)

4.「リンカ」セクションの「全般」で、「追加のライブラリ ディレクトリ」に、以下を追加します。
$(OPEN_NI_LIB)
これは、OpenNIのライブラリファイルのある場所を指す環境変数です。
(デフォルトではC:\Program Files\OpenNI\Lib です。)

5.「リンカ」セクションの「入力」で、「追加の依存ファイル」に、以下を追加します。
OpenNI.lib

6.OpenNIの設定にXMLファイルを使用したい場合、OpenNIの「Data」フォルダにあるサンプルファイルを使用します。
(デフォルトの位置は、C:\Program files\OpenNI\Dataです。)
OpenNIのxmlについて、詳しくは、Xml Scriptsを見てください。

7.上記で説明した、追加のインクルードディレクトリとライブラリディレクトリは、Release構成とDebug構成の両方に設定してください。

8.あなたのコードがCの場合はXnOpenNI.hをインクルードしてください。
C++の場合は、XnCppWrapper.hをインクルードしてください。

Getting Started

Supported Platforms
OpenNIは、以下のプラットフォームをサポートします。
・ Windows XP and later, for 32-bit only
・ Linux Ubuntu 10.10 and later, for x86

Main Objects

・Context Object
contextはOpenNIのメインオブジェクトです。
contextは、アプリケーションが使用しているproduction chainを含む、OpenNIを使用しているアプリケーションの完全な状態を保持します。
同じアプリケーションが1つ以上のcontextを生成できますが、それらのcontextは情報を共有しません。
例えば、認識ミドルウェアは他のcontextのデバイスを使用することはできません。
contextは使用するまえに初期化する必要があります。初期化により、モジュールはロードされ、接続されます。
contextにより使用されたメモリを開放するため、アプリケーションはshutdown関数を呼び出す必要があります。

・Metadata Objects
OpenNIのMetadata Objectは、あるデータのもつプロパティのセットをカプセル化したものです。
例えば、深度マップの典型的なプロパティは、マップの解像度(例えばX方向およびY方向のピクセルの数)です。データを生成するgeneratorは、データを特定するためのMetadata Objectを持ちます。
加えて、Metadata objectは、データ生成時の設定(コンフィグレーション)の記録に重要な役割を果たします。
ノードからデータを読み込んでいるにもかかわらず、アプリケーションが設定(コンフィグレーション)を変更してしまう場合があります。この場合、うまくコントロールしないと、エラーとなってしまいます。
例:
depth generatorがQVGA(320x240)解像度で深度マップを生成するよう設定されており、
アプリケーションはそこから連続的にデータを読み込んでいたとします。
ある時点で、アプリケーションがnodeの出力解像度をVGA(640x480)に設定変更したとします。
新しいフレームデータが届く前は、xn::DepthGenerator::GetDepthMap()を呼び出すと、QVGAのマップが返ってきますが、xn::DepthGenerator::GetMapOutputMode()を呼び出すと、現在の解像度はVGAであると返ってくるため、アプリケーションは不一致に遭遇します。この場合、アプリケーションは受け取った深度マップがVGAであると想定しているため、存在しないピクセルにアクセスしてしまいます。

この場合の解決策は以下のようになります。
個々のnodeはmetadata objectを持っています。metadata objectはデータを読み込んだ際のデータのプロパティを記録しています。上の例の場合、正しい方法は、metadata objectを取得し、そこから解像度を取得することです。

Configuration Changes

OpenNIの設定(コンフィグレーション)オプションは、以下の関数を持ちます。
・Set:設定(コンフィグレーション)を修正する
・Get:現在の値を取得する
・Register/Unregister:オプション変更時のコールバック関数の登録/登録解除を行います。

Data Generators

Map Generator
各種のマップを生成するgeneratorの基本となるインタフェイスです。
主な機能は
・Output Mode property:マップを生成するための設定を制御します。
・Cropping capability
・Alternative Viewpoint capability
・Frame Sync capability

Depth Generator
深度マップを生成するgeneratorです。
主な機能は
・Get depth map:深度マップを生成します。
・Get Device Max Depth:計測可能な最大の距離を取得します。
・Field of View property:センサーの水平方向と垂直方向の角度を設定します。
・User Position capability

Image Generator
カラーイメージマップを生成します。
主な機能は
・Get Image Map
・Pixel format property

IR Generator
IRマップを生成します。
主な機能は
・Get IR Map

Scene Analyzer
センサーの生データを取得し、意味付けしたラベル付きマップを生成するmap generator
主な機能は
・Get Label Map:各ピクセルに意味を持ったラベルを付加したマップを生成します。
(figure1、figure2、backgroundなどのラベルをつけます。)
・Get Floor:床平面の座標を取得します。

Audio Generator
・音声データを生成するオブジェクトです。
主な機能は
・Get Audio Buffer
・Wave Output Modes property:音声出力の設定をします。サンプリング周波数やチャンネル数、ビットレートなどを設定します。

Gesture Generator
人体や手のジェスチャートラッキングを行います。
主な機能は
・Add/Remove Gesture:ジェスチャーのon/offを切り替えます。onにすると、generatorは、ジェスチャーを探し始めます。
・Register/Unregister Gesture callbacks
・Register/Unregister Gesture change

Hand Point Generator
手の位置のトラッキングを行います。
主な機能は
・Start/Stop Tracking:指定した手のトラッキングを開始/終了します。
・Register/Unregister Hand Callbacks:以下のイベントがコールバックを発生します。
新しい手が生成された場合
認識済みの手が移動した場合
認識済みの手を見失った場合

User Generator
空間内の人体データを生成します。
主な機能は
・Get Number of Users:空間内で認識済みのユーザーの人数を返します。
・Get User CoM:ユーザーの中心位置を返します。
・Get User Pixels:ユーザーを表すピクセルを返します。出力は、空間全体のマップで、ユーザーのボディを表すピクセルにはユーザーIDが付加されています。
・Register/Unregister user callbacks:次のアクションがユーザーコールバックを呼び出します。
新しいユーザーを認識した場合
認識済みのユーザーを見失った場合

Backwards Compatibility

OpenNIは完全な後方互換性を保証します。
これは、ある特定のバージョンのOpenNIで作成されたアプリケーションは、
再コンパイルなしで将来のOpenNIのバージョンでも動作することを保証します。

実際場面で、このことは、理想的にはコンピュータには最新のOpenNIがインストールされるべきであることを意味します。
もしそうでない場合、コンピュータにインストールされたアプリケーションから、最新のOpenNIを要求されます。
これを実現するため、アプリケーションはOpenNIも同時にインストールすることを推奨します。

Production Node Error Status

Production Nodeは、それが現在機能しているかどうかを表す、エラーステータスを持ちます。
たとえば、もしデバイスがコンピュータに接続されていなければ、デバイスnodeは機能することができません。
デフォルトのエラーステータスは、Error Status capabilityが実装されていなければ、いつも「OK」です。
このcapabilityは、production nodeに、エラー発生時のエラーステータスの変化を可能にする能力です。
このcapabilityが実装されていない場合、ステータスはいつも「OK」です。

アプリケーションは、エラーのnodeが「どれか」に興味がなく、エラーのnodeがあるかどうかだけ知りたい場合でも、それぞれのnodeのステータスを調べる必要があります。
nodeのエラーステータスが変化した際の通知を受け取るために、アプリケーションはコールバック関数を登録することができます。

OpenNIは、すべてのnodeのエラーステータスを、「Global Error Status」と呼ばれるエラーステータスに集約します。
これは、アプリケーションが、nodeの現在の状態を取得するのを簡単にします。
Global Error Status「XN_STATUS_OK」はすべてのnodeのエラーステータスがOKであることを意味します。
もし、1つのnodeにだけエラーが発生した場合、そのエラーステータスが、Global Error Statusとなります。
(たとえば、もし一つのセンサーが接続されていなければ、Global Error Statusは、XN_STATUS_DEVICE_NOT_CONNECTED になります。)

もし1つより多くのnodeがエラーの場合、Global Error Statusは、XN_STATUS_MULTIPLE_NODES_ERROR になります。このような状況の場合、アプリケーションはすべてのnodeをチェックしてerror nodeを特定し、原因を調べる必要があります。

Recording

Recordingは、強力なデバックツールです。
データをすべてキャプチャし、デバック時に、ストリームを完全に再現することが可能です。

OpenNIは、Production node chainのレコーディングをサポートします。
個々のnodeの完全な設定(コンフィグレーション)とnodeからの全データストリームを記録できます。

OpenNIは、データを記録し、再生するフレームワークを持っています。(再生の際はmock nodeを使用します。)
それらは、nimRecorderモジュールにより実現されます。
nimRecorderモジュールは、".ONI"ファイルフォーマットを定義し、このフォーマットによる記録と再生をサポートします。

General Framework Utilities

OpenNI APIに加えて、アーキテクチャやOSの違いを吸収するため、
以下のユーティリティが用意されています。

・USBアクセス用の抽象レイヤ
・基本的なデータ型の実装(リストやハッシュなど)
・ログとダンプ
・メモリ&パフォーマンスプロファイル
・イベント(イベントに対するコールバックを実現するため)
・タスクスケジューラ

OpenNIを使用するアプリケーションは、これらのユーティリティを使用可能です。
しかし、これらのユーティリティはOpenNIの標準には含まれないため、
完全な後方互換性は保証されません。

Licensing

OpenNIは、モジュールやアプリケーションが使用する、シンプルなライセンスシステムを提供します。
OpenNI Context Object(OpenNIを使用しているすべてのアプリケーションの状態を保持するオブジェクト)は、現在ロードされているライセンスのリストを保持します。
このリストは、あるライセンスを検索する、どの段階でもアクセス可能です。

ライセンスは、ベンダー名と、ライセンスキーから構成されます。
このライセンスシステムを使いたいベンダーは、独自のキーフォーマットを使用することができます。

ライセンスシステムはモジュールによって使用され、モジュールが、認証済みのアプリケーションによって使用されていることを保証します。
特定のコンピュータにインストールされた特定のベンダーの提供するモジュールが、
特定のアプリケーションからのみアクセス可能であることを保証します。

Production Nodeの列挙プロセスにおいて、OpenNIは有効なProduction Chainを探しますが、
その際にモジュールはライセンスをチェックします。もし有効なライセンスが登録されていなければ、
モジュールは自身を隠してしまい、結果として、有効なProduction Chainとはなりません。

OpenNIは、ライセンスキーのグローバル登録もサポートします。
グローバル登録の場合、OpenNI Context Objectを初期化する際にロードされます。
大部分のモジュールはインストールの際にライセンスキーを必要とします。
ユーザーが入力したライセンスキーは、niLicenceコマンドラインツールを使って、グローバルライセンスレジストリに登録されます。niLicenceコマンドラインツールは、登録解除の際にも使用します。

加えて、アプリケーションはモジュールのプライベートライセンスを持つことも可能です。
これは、あるモジュールが、特定のアプリケーションからのみ使用可能であることを意味します。
(他のアプリケーションがモジュールを使用することを禁止します。)