【 KINECT 】センサーの検出
「センサーの検出」、「初期化」、「リソース開放」は、KINECT 操作の基本処理です。
上記の初期化は、センサーを検出しないと行われません。また使用中USBケーブルが外れる可能性があるので、常時監視が必要となります。
この場合アプリケーションは一時停止し、KINECT をもう一度コンピューターに接続するようにユーザーに促す処理が必要となります。
Kinect センサーを検出する方法
アプリケーションでは、コンピュータに Kinect が接続されたことを検出するか、検出通知を受け取る必要があります。
KinectSensor クラスには、KinectSensors という KinectSensorCollection 型の静的プロパティがあります。
KinectSensorCollection は ReadOnlyCollection から継承し、1つのインデクサーと StatusChanged
という1つのイベントからなるシンプルなオブジェクトです。
このインデクサーを使用して、KinectSensor オブジェクトにアクセスします。
コレクションの要素数は、接続されている Kinect の数と常に同じになります。接続台数の制限はありません。( CPU の能力まで接続できます。)
Kinect が接続されてることは、コレクションを反復するだけで簡単に検出できますが、KinectSensor コレクションに要素が含まれているだけでは
Kinect をすぐに
使用することはできません。
KinectSensor オブジェクトには、デバイスの状態を示す Status プロパティがあります。 プロパティの型は、列挙型の KinectStatus
です。
下記に、このプロパティのさまざまな状態値とその意味を示します。
状 態 値 |
意 味 |
undefined |
接続されたデバイスが特定できない |
Connected |
デバイスが接続済みで、ストリームからデータを生成可能 |
DeviceNotGenuine |
接続されたデバイスが認可された Kinect センサーではない |
Disconnected |
デバイスとのUSB接続が切断されている |
Error |
デバイスとの通信でエラーが発生している |
Initializing |
デバイスがコンピュータに接続されていて、接続プロセスを実行中 |
InsufficientBandwidth |
デバイスを操作するのに必要な帯域幅がUSBコネクタに無い為、Kinect を初期化できない |
NotPowered |
Kinect の電源が不十分、Kinect ハードウエアを動作させる為に、USB接続からの電源から外部電源の切替が必要 |
NotReady |
Kinect が接続されていても、まだ Connected 状態になっていない |
KinectSensor は、Connected 状態にならないと初期化できません。
アプリケーション実行中にセンサーの状態が変化することがあります。従って、アプリケーションでは、接続されているデバイスの状態変化を監視し、状態変化やユーザー
エクスペリエンスのニーズに適切に反応する必要があります。
プログラム

メンバー変数
public partiasl class MainWindow : Window
{
#region メンバー変数
private KinectSensor _Kinect;
#endregion メンバー変数
|
アプリケーションでは、_Kinect メンバー変数を使って使用する KinectSensor オブジェクトへの参照を常に保持しておきます。
また、アプリケーションでセンサーを使い終わった時に、KinectSensor のリソースを解放する為にこの変数が必要です。Kinect プロパティは、このメンバー変数の
ラッパーの役割を果たします。
このプロパティを使用する主な目的は、センサーのすべての初期化とリソース解放を共通の場所に置いて、体系的に実行することです。
プロパティのセッターでは、受け取った状態値が KinectStatus.Connected の場合のみ、_Kinect メンバー変数を設定します。
また、Kinect プロパティに値を代入する時も状態が Connected のデバイスのみを探すようにしています。Connected 状態でないセンサーを初期化しようとすると
InvaliedOperationException 例外が発生します。

コンストラクタ
#regain コンストラクタ
public MainWindow()
{
InitializeComponent();
this.Loaded += ( s, e ) => { DiscoverKinectSensor(); };
this.Unloaded += ( s, e ) => { this.Kinect = null; };
}
#endregion コンストラクタ
|
コンストラクタ内には2つの匿名メソッドがあります。
1つは、Loaded イベントに応答し、もう1つは、Unloaded イベントに応答します。
Loaded イベントは、ウインドウの Loaded イベントに応答して、DiscoverKinectSensor メソッドを呼び出し、センサーの接続を検出します。
Unloaded イベントは、ウインドウのUnloaded イベントに応答して、Kinect プロパティを Null に設定して使用していたセンサーのリソースを解放します。

センサーを開始する
KInect を検出したら、Kinect がデータの生成を開始するように、初期化する必要があります。
初期化プロセスは3段階で行います。
@ まずアプリケーションで処理するストリームを有効にします。
それぞれのストリームに、そのストリームを初期化する Enabled メソッドがあります。
ストリームは1つ1つ異なり、有効にする前に構成しておく必要のある設定があります。
ストリームによっては、こうした設定がプロパティであったり、Enabled メソッドのパラメーターであったりします。
A 次に、ストリームからデータを取得する方法を決めます。
最も一般的なのは、KinectSensor オブジェクトの一連のイベントを使用する手法です。
イベントには、ストリームごとのイベントと、全ストリーム対応のAllFrameReady イベントがあります
B 最後に、Start メソッドを呼び出して、KinectSensor オブジェクトを開始します。
Start メソッドを呼び出すと、ほぼ同時にフレーム準備完了イベントが発生します。
その為、受け取る Kinect データを処理する準備が整ってから KinectSensor を開始します。
#region メソッド
private void DiscoverKinectSensor()
{
KinectSensor.KinectSensors.StatusChanged += KinectSensors.StatusChanged;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault( x.Status ==
KinectStatus.Connected );
}
private void KinectSensors.StatusChaged ( object sender, StatusChangedEventArge
e )
{
switch ( e.Status )
{
case KinectStatus.Connected;
if ( this.Kinect == null )
[
this.Kinect = e.Sensor;
}
break;
case KinectStatus.Disconnected;
if ( this.Kinect == e.Sensor )
[
this.Kinect = null;
this.Kinect = KinectSensor.KinectSensors.FirstOrfault ( x => x.Status
== KinectStatus.Connected );
if ( this.Kinect == null )
{
// センサーが接続されていないことをユーザーに通知する
}
}
break;
// 必要に応じて、他のすべての状態を処理する
}
}
#endregion メソッド
|

センサーを停止する。
開始した KinectSensor は、Stop メソッドを呼び出して停止します。
データの生成はすべて停止しますが、最後にもう一度フレーム準備完了イベントの発生が予想される為、フレーム準備完了イベントハンドラにフレームオブジェクトは
Null かどうかのチェックを必ず追加します。
センサーの停止プロセスは非常に簡単ですが、停止する目的はやや複雑で、アプリケーションのアーキテクチャに影響を与えることがあります。
Stop メソッドが用意されている理由は、オンになっているスイッチをすべてオフにするためというように単純な話ではありません。
KinectSensor オブジェクトとそのストリームにはシステムリソースが使われます。すべてのアプリケーションが適切に動作するためには、使わなくなったリソースを
解放しなければなりません。
#region プロパティ
public KinectSensor Kinect
{
get { return this.Kinect; }
set
{
if ( this.Kinect != null )
{
// ここにセンサーを停止するコードを記述
this.Kinect = null;
}
if ( value != null && value.Status == KinectStatus.Connected
)
{
this.Kinect = value;
// ここにセンサーを開始するコードを記述
}
}
}
#endregion プロパティ
}
|
実行結果