2012年1月9日月曜日

Xtionがやってきた。

Xtionがやってきたので、少し触ってみる。
XtionはKinectと同様にOpenNIを利用したモーションキャプチャーです。
Kinectは現状ではハードウェアが商用利用は不可ですが、Xtionは商用利用が可能です。

特に商用利用が目的ではないのですが、
USBバスで動作するのでこちらを購入したというところが強いのですが、
Kinectで行うとハック感がなくなるかな?というところで、
Xtionにしました。Xtion Pro Liveです。

OpenNIのインストール
まず付属してたDVDだと古そうだったので 本家からPackageを入れます。 古い記事だと64ビットだと動作しないみたいな話がありますが この時点では動作するようです。 Macについては後述しておきました。
どんなものを作るのか?
友人が電子書籍系をやっているのだけど「マイノリティ・リポートやろうぜっ」って感じだったので そういうものを作ろうと思った。 動かすのはiPadのようなタブレットだった。iPadにOpenNIとか非現実的な事だし、 私自身がxcodeでソレ系のアプリを作る気もないし、 とにかく相手にプッシュする方法が必要だったので、 相手がサーバでこっちがクライアントという選択肢だと、 こっちから接続しなきゃいけないし、何かと不便に感じた。 ちょうどRFCにWebSocketが載ったところだったのでこっちをサーバにしてWebSocketを実装する事にした。 Javaで動作するものを作ろうと思ったのでJettyでWebSocketサーバを作成して、 そこから何らかのクライントでWebSocketにアクセスしてもらって通信をやろうと思った。
WebSocketを作る
ここを参考に サーバサイドは作成した。 実際はChatRoom的な管理は必要ないわけだけど、 例えばHTML(WebSocketでアクセスできるもの)で資料を作って それをみんなの端末で見る~。。。なんてI/Fも想定してたりしてなかったり。
HandTrackerを発見!
はじめはサンプルの「UserTracker」を元に作り始めた。 Userを認識してSkeletonCapabilityで骨格を認識させて、 それで手の動きを見ようと考えていたんだけど、 「GestureGenerator」「HandsGenerator」が存在する事を知り ココに「HandTracker」のサンプルがあるので拝借。 ※っていうか最新のパッケージならローカルにも展開されてます。 サンプル読んだおかげで大体の動作は理解できた。 ・Contextやら読み込んで各Generatorを初期化 ・イベントに対してObserverを作成(コールバック) ・ループして ・ノードを更新してノードからデータを取得 ・何かやる みたいな流れみたい。
HandsGeneratorでジェスチャーを認識
このサンプルにGestureGeneratorに対して"Click"とあり、 これがセンサーに向かって手をpullしたり、調べた限りだと"Wave"などを認識できるようなんだけど 「これにLeftとかRightをかあれば楽?」と考えたりもしたけど この辺りを読むと サンプルの通りGestureGeneratorで認識させてからHandsで行うのが通常の使い方みたい。 サンプルは ・GestureGeneratorに"Click"を登録 ・イベント発生でHandsGeneratorのトラッキングを開始 ・Update系のイベントでそのポイントを取得して履歴に残す ・ポイントの履歴を描画 ・手の認識が終わったらGestureGeneratorの"Click"を再度登録 みたいな流れ。 Updateで履歴があるのでこれを使って
 public static SocketType getType(float modX, float modY, float modZ) {

  SocketType type = SocketType.NONE;
  if ( Math.abs(modY) < margin ) {
   if ( modX < (movement*-1) ) {
    type = SocketType.LEFT;
   } else if ( modX > movement ) {
    type = SocketType.RIGHT;
   }
  } else if ( Math.abs(modX) < margin ) {
   if ( modY < (movement*-1) ) {
    type = SocketType.DOWN;
   } else if ( modY > movement ) {
    type = SocketType.UP;
   }
  } else {
   if ( modZ < (movement*-1) ) {
    type = SocketType.ZOOMIN;
   } else if ( modZ > movement ) {
    type = SocketType.ZOOMOUT;
   }
  }
  return type;
 }
みたいな座標の移動量を計算させて、どっちに動いているかを判定 ※SocketTypeってのはオリジナルのEnumです。 あとはソケットで送るだけ。 まぁこれだと調整値によって認識とかしまくりとか認識しないとかさんざんなので もう少し何かする必要があるかな?
感想
何かライブラリ使ってもう少し何かできそうな流れだったけど、 自分で理解するのも含めて作ってみた。 サンプルを理解したところをもう少し書きたかったんだけど、 またそれは別の機会でもあれば。

0 件のコメント: