今回は、前回に登録した「画像を表示する準備ができたとき」に呼ばれるイベントハンドラと、「関節(骨格)のデータを提供する準備できたとき」に呼ばれるイベントハンドラという、二つのイベントハンドラを実装します。これが完了すればKinect向けのアプリはほぼ完成です。

RGB画像を表示する

 nui_ColorFrameReadyイベントハンドラではKinectセンサーから取得したRGB画像を、リスト1のXAMLファイルで設定したGUI部品「Imageオブジェクト」に表示するための処理を記述しています。

 RGB画像のデータ(1ピクセル4バイトで表現される配列)はイベントハンドラの引数「e.ImageFrame.Image.Bits」から取得可能です(リスト2の(6))。この画像データの配列をSystem.Windows.Media.Imaging.BitmapSourceクラスのCreateメソッドで画像に変換し、Imageオブジェクトのデータとして設定しています。この処理を1秒間に最大30回実行するので、画面では“動画”に見えるのです。

関節の座標を取得する

 もう一つのイベントハンドラ、nui_SkeletonFrameReadyの処理はKinectプログラミングにおける最重要ポイントです。ここでは、任意の関節の3次元座標値(x, y, z)を取得しています。

図10●Kinectセンサーが追跡できる関節。全部で20カ所
図10●Kinectセンサーが追跡できる関節。全部で20カ所
[画像のクリックで拡大表示]

 Kinectが追跡できる関節は図10の通りで、20カ所あります。また、Kinectは同時に6人を認識し、そのうちの2人の関節を追跡できます。

 実際の関節のデータはイベントハンドラの引数「e.SkeletonFrame.Skeletons」から取り出せます。ですから、foreachループで識別可能な6人について「関節を追跡できているか?」を調べ、追跡できているプレイヤーの任意の関節の座標値を取り出せばよいでしょう(リスト2の(7))。このプログラムでは右手の座標値を取得しています。

 他の関節の座標値を取り出したい場合は「JointID.HandRight」の部分を「JointID.Head」(頭)などに変えるだけです。表5を参考に、いろいろ試してみましょう。

表5●各関節を表す定数の一覧
表5●各関節を表す定数の一覧

 プログラムでは座標値が得られたら、getDisplayPositionメソッドで画面の座標値に変換し(リスト2の(8))、青いボールを動かしています(リスト2の(9))。getDisplayPositionはSkeletal Viewerサンプルにあるメソッドをそのまま流用したものです。適切な座標変換を行ってくれます。

 これで完成です。BlueBallのプロジェクトは日経ソフトウエアのWebサイトからダウンロードできます。

 このように、SDKを利用すれば右手を認識するようなプログラムならとても簡単に作れます。冒頭で紹介したKinect Earth Moveも、このBlueBallの延長線上で作れるので、ぜひソースコードを入手して試してみてください。

 この記事はXbox版Kinectセンサーを対象に「Kinect for Windows SDK」ベータ版が提供されていた2011年10月の状況を元に解説しています。その後、2012年2月にWindows版KinectセンサーとKinect for Windows SDKの正式版が提供され、SDKのダウンロード場所、SDKの中身、ライセンス条件、クラスライブラリ構成などが変更されています。正式版の情報については、MSDNの『Microsoft Kinect For Windows SDK - V1.0 リリース ノート』を併せてご覧ください。
川西 裕幸(かわにし ひろゆき)
日本マイクロソフト エバンジェリスト。北海道大学理学部物理学科卒。3Dグラフィックスおよびユーザーエクスペリエンスが専門。DirectX SDKドキュメントやWindowsユーザーエクスペリエンスガイドラインの日本語版を担当するとともに、「Game Programming Gems」シリーズ(ボーンデジタル)などを翻訳・監修。CEDEC AWARDS 2010著述賞を受賞。趣味は薪割り。