2011年6月19日日曜日

Sharing Devices between Applications and Locking Nodes

ほとんどのケースでは、OpenNIのnodeが生成するデータは、ハードウェアデバイスからやってきます。
ハードウェアデバイスは、1つ以上の設定(コンフィグレーション)を設定できます。
ゆえに、いくつかのアプリケーションが同時に同じデバイスを使用する場合、
その設定(コンフィグレーション)は同期されなければなりません。
しかし、通常、アプリケーションを書いているときに、他のどんなアプリケーションが同時実行されるのか知ることはできないので、設定の同期は不可能です。
加えて、アプリケーションが、ある特定の設定を必要とし、他の設定ではアプリケーションが正常に動作しない場合もあります。

OpenNIでは、複数のアプリケーションがハードウェアデバイスを共有するための2つのモードを用意しています。

・Full Sharing(default)
このモードでは、アプリケーションは設定ハンドラを宣言します。
OpenNIインターフェースは、設定変更時に呼ばれるコールバック関数を登録できるようにします。
これにより、設定変更時にはアプリケーションは通知を受け取ることができます。
(設定を変更したのがアプリケーション自身であっても、他のアプリケーションであっても通知を受け取ります。)

・Locking Configuration
このモードでは、アプリケーションは、あるNodeの現在の設定をロックする要求を発行します。
このため、このモードでは、OpenNIは「Set」関数の呼び出しを許可しません。
nodeがハードウェアデバイスである場合(または、プロセス境界を越えて共有されるようなオブジェクトの場合)、nodeは「Lock Aware」capabilityをサポートする必要があります。
「Lock Aware」capabilityは、プロセス境界を越えてロックする能力を意味します。

注
nodeがロックされた場合、ロックしたアプリケーションはロックハンドルを受け取ります。
nodeをアンロックすることに加えて、このハンドルは、ロックを解除することなしに、設定を変更することを可能にします。
(他のアプリケーションに設定を盗まれないようにするためです。)

Generating and Reading Data

Generating Data

前に示したように、データを生成するProduction nodeを、「Generator」と呼びます。
Generatorの生成後は、アプリケーションによる設定が必要となる場合があるため、
即座にデータの生成を開始するわけではありません。

このことは、アプリケーション提供されるデータは、アプリケーションによる設定に従って生成されていることを保証します。

Generatorは、データを生成するよう指示されるまで、データを生成しません。

xn::Generator::StartGenerating() 関数は、データ生成を開始するのに使用します。
また、アプリケーションは、xn::Generator::StopGenerating()を使用することで、nodeを破棄せずにデータ生成を中断し、nodeの設定を変更することができます。

Reading Data
Data Generatorは、連続的に新しいデータを生成します。
しかし、アプリケーションは、古いデータもまた使用可能です。(たとえば、深度マップの前のフレームデータなど)
この結果として、generatorは、新しいデータの取得を明示的に指示されるまで、新しいデータを内部的に保持します。
このことは、アプリケーションが「UpdateData」関数によって明確に指示するまで、Data Generatorは新しいデータを内部に隠していることを意味します。
OpenNIは、xn::Generator::WaitAndUpdateDate()関数によって、新しいデータが取得可能になるまで、アプリケーションを待機させることができます。

あるケースでは、アプリケーションは1つ以上のnodeを持ち、すべてのnodeのupdateが必要になることがあります。
OpenNIはこれを行うための関数をいくつか用意しています。
これらの関数の違いは、UpdateAllの引き金となるイベントの違いです。
・xn::Context::WaitAndUpdateAll()
待機中のnodeの1つで新しいデータが取得可能になったとき、すべてのnodeをupdateする
・xn::Context::WaitOneUpdateAll()
ある特定の1つのnodeを監視し、そのnodeの新しいデータが取得可能になったとき、すべてのnodeをupdateする。これは、複数のnodeがあるが、そのうちの1つのnodeがアプリケーションの進行を決定する場合に有効です。
・xn::Context::WaitNoneUpdateAll()
待機せずに、即座にすべてのnodeをupdateします。
・xn::Context::WaitAndUpdateAll()
すべてのnodeを待機し、すべてのnodeで新しいデータが取得可能になったら、updateします。

上記の4つの関数は、2秒のタイムアウト後に終了します。
ある特定のnodeのみupdateする必要がある場合を除いて、通常はxn::Context::Wait[...]UpdateAll()関数を使用することを強く推奨します。
すべてのnodeをupdateすることは、以下の点で有益です。
・nodeが相互に依存している場合、目的のnode(アプリケーションがupdateしたいnode)が依存しているnode(このnodeは、より低レベルなnodeで、他のnodeにデータを供給するnodeです。)が、updateされた後に、目的のnodeがupdateされることを保証します。
・記録からデータを再生している場合、条件に合致するまで再生を続けます。
・recorderが存在する場合、この関数は自動的にrecorderの対象となるnodeからの記録を始めます。


Mock Nodes

OpenNIはnodeのMock実装をサポートします。
nodeのMock実装は、データの生成ロジックを一切含みません。
代わりに、(アプリケーションや、他のnode実装などの)外部コンポーネントに対して設定変更やデータを与えることを可能にします。
アプリケーションがMock nodeを必要とするケースはまれです。
ただ、データ再生を行うnodeが、データ読み込みの際に、実際のnodeをシミュレートする場合は有用です。

Capabilities

Capabilities mechanismは、複数のミドルウェアとデバイスをOpenNIに登録できる、という柔軟性を提供します。

OpenNIは、異なるベンダーが能力を変更したり、コンフィグレーションオプションをProduction Nodeに提供するのを許可します。それゆえに、ある種のオプション拡張がOpenNIによって定義されています。

それらのオプション拡張に関するAPIは、「Capabilities」と呼びます。
また、その拡張を実装するかどうか、ベンダーが決めることができます。
Producion Nodeは、ある能力をサポートしているかどうか問い合わせることができます。
その問い合わせは、個々のnodeに対して行われます。

OpenNIは、能力のセットを提供しており、このセットは将来追加される可能性があります。
モジュールは、自分がサポートする能力を宣言することができます。
さらに、Produciton Chainの列挙時、アプリケーションは、特定の能力を必須条件として指定することができます。その場合、指定された能力をサポートするモジュールのみが返されます。

現在サポートされているcapabilities

・Alternative View
マップを生成する型(深度マップ、イメージマップ、IR)に対し、センサーが別の場所にあるかのように、マップデータを変換する能力
「別の場所」は、他のProduction Nodeによって提供され、通常、他のセンサーが出力するマップです。

・Cropping
マップを生成する型(深度マップ、イメージマップ、IR)に対し、フレーム全体ではなく、指定領域のみを出慮kうする能力。
Croppingが有効な場合、生成されるマップのサイズは、より低い解像度となります。
たとえば、map generatorがVGA(640x480)で出力し、アプリケーションが300x200サイズのCroppingを指定した場合、横1行のピクセル配列のサイズは300ピクセルになります。
Croppingは、パフォーマンスチューニングに有効です。

・Frame Sync
2つのフレームデータを生成するセンサー(たとえば、深度センサーとイメージセンサー)に対し、それらのフレームの同期をとることができる能力です。

・Mirror
generatorによって生成されたデータを鏡像反転する能力。Mirroringは、センサーが人物の正面に置かれている場合に有効です。(その場合、センサーが取得したデータは鏡像反転されている、つまり右手が左手の位置にあるため)

・Pose Detection
user generatorの能力で、人物がある特定の位置でポーズをとったことを認識する能力。

・Skeleton
user generatorが、人体のデータを、Skeletonデータとして出力する能力。
このデータは、間接の位置データを含みます。
また、Skeletonの位置をトラッキングする能力、user calibrationの能力も含みます。

・User Position
深度Generatorが、空間の特定の領域に関する出力を活用する能力

・Error State
nodeが、エラー状態であることを通知する能力。
「エラー」とは、実用上、nodeが適切に機能しない状態を言います。

・Lock Aware
nodeが、ある領域の外側をロックする能力。詳しくは、「アプリケーション間のデバイス共有とNodeロック」(Sharing Devices between Applications and Locking Nodes)を見てください。

Production Chains

前の章で説明したように、複数のモジュール(センサーと認識ミドルウェア)を同時にOpenNI実装に登録することができます。
この構成は、アプリケーションに、データの取得や処理に使用するセンサーや認識ミドルウェアの選択の柔軟性を与えてくれます。

Production Chainとは?

Production Nodeの章で、user generator型のProduction Nodeがアプリケーションによって生成される例を見ました。
人体データ(body data)を生成するために、このProduction Nodeは、より低レベルのProduction Nodeであり、センサーから生データを取得するdepth generatorを使いました。
この例で、Production Nodeのシーケンス(user generator -> depth generator)は、人体データを生成するために互いに依存しており、これをProduction Chainと呼びます

異なるベンダーが、同じProduction Node型の実装を提供することができます。

例:
Aブランドがuser generatorの実装を提供しているとし、Bブランドがまた別のuser generatorの実装を提供しているとします。
両方のgeneratorはアプリケーションの開発者が利用可能です。
OpenINは、アプリケーションが、どのモジュールを使用するか、どのProduction Chainを使用するか、定義することを可能にしています。
OpenNIは、登録済みのモジュールから、可能なProduction Chainの組み合わせをすべて列挙します。
アプリケーションは、好ましいブランドや、バージョンなどに従って、そこから1つのChainを選択します。
注:アプリケーションは、chainを特定せず、OpenNIから、最初のchainを取得することも可能です。

普通、アプリケーションは、chainの最上位にのみ興味があります。
これは、アプリケーションにとって使い物になるレベルのデータを提供してくれるnodeだからです。
たとえば、hand point generatorなど。

OpenNIでは、その下にあるchainを意識することなしに、アプリケーションが一つのnodeだけを利用することも可能です。
詳細な設定のために、このchainにアクセスして、個々のnodeを設定することも可能です。

たとえば、前に、OpenNIに複数のモジュール(認識ミドルウェアとデバイス)を登録する例を見ました。
その場合、アプリケーションがuser genertorを要求すると、OpenNIは以下のように、人体データを取得するための4種類のProduction Chainを返します。

上図は、以下のモジュールがOpenNIに登録された場合の例です。
・異なるベンダーの供給する、2つの人体認識見取るウェア。
・異なるベンダーの提供する、2つの3Dセンサー。

上図は、この実装中で見つかった、4つの選択可能なProduction chainを表します。
それぞれのChainは、人体認識ミドルウェアと3Dセンサーの可能な組み合わせを表します。
OpenNIは、アプリケーションが上の4つから1つを選択できるようにします。

2011年6月18日土曜日

Production Node

「意味のある」3Dデータは、空間を翻訳し、理解することによって得られます。
意味のある3Dデータの生成は複雑な仕事です。

典型的には、この仕事は生データを出力するセンサーを使います。
この生データは、各ピクセルがセンサーからの距離になっているdepth mapであることが多いです。
専用のミドルウェアでこれを処理し、アプリケーションに渡すための上位データを生成します。

OpenNIでは、「Production Node」という言葉を定義します。
Production Nodeとは、NIアプリケーションに必要なデータを生成する過程において、生産的な役割を果たすコンポーネントのことです。
Production Nodeは、ある特定のデータ生成に関わる機能一式をカプセル化したものです。
Production Nodeは、OpenNIがアプリケーションに提供するインタフェースの基本的な構成要素となるものです。
しかしながら、Production NodeのAPIは、インタフェイスなど標準的なルールを定義するだけです。データを生成するロジックは、OpenNIに登録されたモジュールで実装する必要があります。

たとえば、手の位置を生成する機能一式を揃えたProduction Nodeがあったとして、
手の位置データの生成ロジックは、OpenNIに登録され、かつそのようなデータ生成ロジックを実装した、OpenNI外部のモジュールが行わなければなりません。

原則として、Production Nodeは、特定のデータを生成する、独立した存在です。
そして、生成したデータを、他のProduction Nodeや、アプリケーションなど、様々なオブジェクトに提供します。
しかし、中には、他の低レベルデータを生成するProduction Nodeに依存し、その低レベルデータを分析してアプリケーションにデータを提供するProduction Nodeも存在します。

例
3次元空間内の人間の動きをトラッキングするアプリケーションを考えてみましょう。
このアプリケーションは、人体データを提供してくれるProduction Nodeが必要です。
このようなProduction Nodeを「user generator」と呼びます。
user generatorは、元データを「depth generator」から取得します。
depth generatorはセンサーによって実装されたProduction Nodeで、深度センサーから生のセンサーデータを取得し、(たとえば、毎秒Xフレームのストリームデータです。)そして、深度マップとして出力します。

より上位のレベルの例をいくつか見てみましょう

1.1ユーザーの手の位置の取得
ユーザーの手のひらの中心(よく、ハンドポイントと呼ばれる点です)や、指先を出力します。

2.空間内の人体の取得
人体の間接の現在の位置と向きを出力します。
(よく、人体データ(=body data)と呼ばれます。)

3.手のジェスチャーの認識
出力は、特定のジェスチャーが発生した、というアプリケーションへのメッセージになります。

Production Node型
Production Nodeは型をもっており、次のいずれかのカテゴリに分類されます。
1.Sensor-Related Production Nodes
2.Middleware-Related Production Nodes

現在、OpenNIでは以下のProduction Node型をサポートします。

1.Sensor-Related Production Nodes
・Device
物理デバイスを表現するProduction Node
(たとえば、深度センサーやRGBカメラ)
この Production Nodeの目的は、デバイスの設定を行うことです。

・Depth Generator
深度マップを生成するProduction Node。
OpenNI準拠の3Dカメラによって実装されます。

・Image Generator
カラーイメージマップを生成するProduction Node。
OpenNI準拠のカラーセンサーによって実装されます。

・IR Generaotr
IRイメージマップを生成するProduction Node。
OpenNI準拠のIRセンサーによって実装されます。

・Audio Generator
音声ストリームを生成するProduction Node。
OpenNI準拠のオーディオデバイスによって実装されます。

2.Middleware-Related Production Nodes

・Gestures Alert Generator
あるジェスチャーが行われた場合に、アプリケーションへのコールバックを生成します。

・Scene Analyzer
空間の分析を行い、背景と対象物を分離し、空間内の人体を認識し、床平面を検出します。
Scene Analyzerの主な出力は、ラベル付けされた深度マップです。
ラベルはピクセル単位に付けられ、そのピクセルが人体なのか、背景なのかを表します。

・Hand Point Generator
手の検出とトラッキングを行います。
このProduction Nodeは、ハンドポイント(手のひら)を検出した際のコールバックを生成します。
また、トラッキングが有効な場合は、その位置が変化した際のコールバックを生成します。

・User Generator
空間内の人体(全体または一部)を検出します。

レコーディングのために、以下のProduction Nodeがサポートされています。
・Recorder
データの保存を実装します。

・Player
保存されたデータを読み込み、再生します。

・Codec
保存の際の圧縮や解凍に使用します。

OpenNIの階層

下の図は、OpenNIのコンセプトを階層で表したものです。

最上位:NIアプリケーションを指します。
中間:OpenNIそのものです。センサーと、センサーからのデータを分析する認識ミドルウェアの間のインターフェースを定義します。
最下層:視覚および聴覚デバイスを指します。

モジュール

OpenINは、物理デバイスと、認識ミドルウェア間のインターフェースを定義します。
APIは、OpenNIフレームワークに、たくさんのコンポーネントを登録することが可能です。
それらのコンポーネントは「モジュール」と呼ばれ、センサーデータを生成したり、処理したりします。
必要なデバイスを選んだり、必要な認識ミドルウェアを選ぶのは簡単で柔軟性があります。

モジュールには現在、以下の2種類があります。

1.センサーモジュール
3Dセンサー
RGBカメラ
IRカメラ
マイクロフォン

2.ミドルウェア
・人体認識ミドルウェア:センサーデータを分析し、人間の体に対応するデータを生成するプログラムです。

・手認識ミドルウェア:センサーデータを分析し、人間の手の位置などを生成するプログラムです。

・ジェスチャー認識ミドルウェア:あらかじめ定義されたジェスチャーを認識し、ジェスチャーを認識した場合にアプリケーションに通知するプログラムです。

・空間認識ミドルウェア:画像データを分析に、以下のような情報を生成するプログラムです。
1.背景と対象物の分離
2.床平面上の座標
3.空間中の物体の識別

例

下の図は、OpenNIに5つのモジュールが登録された様子を表します。
うち2つのモジュールは、3Dセンサーです。
残りの3つのモジュールは認識ミドルウェアで、2つは人間の全身データを生成し、もう1つは手の位置をトラッキングします。


プログラムやセンサーをOpenNI準拠とするためには、いくつかのインターフェイスを実装する必要があります。

概要

1.NIについて
NI(=Natural Interaction)とは、主に視覚や聴覚などの人間の感覚を利用したコンピュータの操作を指します。
マウスやキーボードに代わって、視覚デバイスや聴覚デバイスをコンピュータ操作に用いるという発想です。
すでに、以下のようにNIは利用されています。
・音声認識技術。コンピュータへの命令を、人間の声によって与えることができます。
・ジェスチャー認識。あらかじめジェスチャーを決めておくことで、ジェスチャーをコンピュータへの命令とすることができます。たとえば、リビングに置いた家電製品を、手の動きで操作することができます。
・人体トラッキング。人の動きを認識することは、ゲームに利用されています。

2.OpenNIについて
OpenNI (Open Natural Interaction)は、NIのための、言語、プラットフォームに依存しないフレームワークです。
OpenNIは、NIを利用したアプリケーションを書くためのAPIを提供します。

OpenNIの目的は、以下の両者が通信するための、標準的なAPIを定義することです。
・センサー(視覚および聴覚)
・視覚および聴覚の認識ミドルウェア

※「認識ミドルウェア」とは、センサーからのデータを元に、そのデータを解析して、意味を解釈するプログラムのことを指します。
たとえば、画像データを受け取って、手のひらを検出し、その位置を返すようなプログラムです。


OpenNIは、物理的なセンサーデバイスや認識ミドルウェアの実装そのものではなく、
アプリケーションが、個々のセンサーデバイスや認識ミドルウェアを部品として利用するための標準的な規格を定めるものです。
OpenNIは、センサーによって実装されたAPIと、認識ミドルウェアによって実装されたAPIを提供します。
センサーと認識ミドルウェアの間の依存性を取り除くことによって、OpenNIは、アプリケーションを異なる認識ミドルウェア上で動作させるための作業を不要にし、移植を容易にします。
(“write once, deploy everywhere”)

また、認識ミドルウェアの開発者は、最上位データを処理するアルゴリズムを書けばよく、どんなセンサーがそのデータを生成したかを意識する必要はありません。

さらに、センサー製造者には、OpenNI準拠のアプリケーションを動かすためのセンサーを作るための仕様を提供します。

OpenNI APIは、センサーデータから計算されたデータを用いて、3Dトラッキングが可能です。
アプリケーションは、センサーやミドルウェアの提供者について意識する必要はありません。

OpenNIは、オープンソースのAPIです。