書籍転載:KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版(2)
UnityでKinectを使う(カラー画像/赤外線画像/Depthデータ/Body)
― Chapter 6 Kinect for Windows SDK v2をUnityで使う 6.3 ―
Unity+Kinectの開発環境が整ったら、実際にUnityからKinectの機能を使ってみよう。UnityによるKinect活用の基礎を解説。
UnityでKinectを活用する方法を紹介します。前回はUnityとKinectの開発環境の構築方法を説明しました。今回はその続きです。
書籍転載について
本コーナーは、秀和システム発行の書籍『KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版』の中から、特にBuild Insiderの読者に有用だと考えられる項目を編集部が選び、同社の許可を得て転載したものです。
『KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版』の詳細や購入は秀和システムのサイトや目次ページをご覧ください。プログラムのダウンロードも、秀和システムのサイトから行えます。
ご注意
本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどはBuild Insiderのそれとは一致しません。あらかじめご了承ください。
■
6.3 UnityでKinectを使う
それでは実際にUnityでKinectの機能を使ってみましょう。
まずはカラー画像を表示させてみます。先ほど追加したKinectViewにあるクラスを使うことで、コードを書かずに開発することができます。
KinectViewの中身を見てみましょう。MaterialsフォルダーとScriptsフォルダーが見つかるはずです。
MaterialsフォルダーにはBoneMaterialが含まれます。これはBodyの関節を表示する際のマテリアルで、後ほど使います。
Scriptsフォルダーには各種C#スクリプトが含まれており、これらはGameObjectに貼り付けて利用します。ManagerまたはViewと命名されたクラスが見えますが、ManagerがKinect SDKから取得したデータを保持するクラス、ViewがそれらをGameObjectに表示するクラスとなります。
6.3.1 カラー画像を表示する
例えばCubeのようなGameObjectにColorSourceMangerとColorSourceViewを追加し、設定を少し加えれば、簡単にカラー画像を表示させることできます。
実際にやってみましょう。まず「Hierarchy」ビューに「Cube」を追加します。続いて「Position」と「Rotation」のX、Y、Zはすべて0に、「Scale」はX=19.2、Y=10.8、Z=1に設定します。「Scale」の数値はKinectのカラー画像の解像度が1920×1080であることを考慮して決めました。
「Cube」に「ColorSourceManager」と「ColorSourceView」を設定します。
「Project」ビューから2つのスクリプトをそれぞれ「Cube」にドラッグアンドドロップします。「Cube」の「Inspector」ビューで2つのスクリプトが追加されていることを確認します。
「Inspector」ビューの「Color Source View」にある「Color Source Manager」に「ColorSource Manager」スクリプトが設定されたGameObjectを設定します。
ここでは「Cube」自身を「Color Source Manager」へドラッグアンドドロップします。
この操作を実行すると「Cube」にKinectのカラー画像が表示されます。
このようにUnityでは簡単にKinectのカラー画像データを表示させることができます。
カラー画像データを取得するColorSourceManagerは、UnityのUpdate()周期ごとにカラー画像を取り込み、Texture2Dに変換しています。このTexture2DはGetColorTexture()で取得できます。
更新のあいだに画像処理を挟むときなど、テクスチャ化されていないバイト列のデータが必要な場合には「_Data」という変数があるので、これを使って外に出せるようにします。
public byte[] GetData()
{
return _Data;
}
|
カラー画像を表示するColorSourceViewでは、Update()周期ごとに先のTexture2DをColorSourceViewのGameObject(ここではCube)のメインテクスチャに設定しています。
6.3.2 赤外線画像を表示する
赤外線画像の表示手順はカラー画像と同じです。まず「Cube」を配置し、「Position」「Rotation」はすべて0、「Scale」はX=10.24、Y=8.28、Z=1に設定します。「Scale」の数値は赤外線画像の解像度が512×424であることを考慮して決めました。
「Cube」に「InfraredSourceManager」と「InfraredSourceView」を設定し、「InfraredSource View」にある「Infrared Source Manager」に「Cube」を設定します。
以上で設定は完了です。これを実行すると、Cubeに赤外線画像が表示されます。
「InfraredSourceView」は「ColorSourceView」と同じです。Update()周期ごとにテクスチャを更新します。テクスチャを作る「InfraredSourceManager」についてはカラー画像と比べて少し処理が追加されています。Texture2DはBGRA32というKinectのカラー画像と同じフォーマットで画像を作成します(フォーマットの詳細については「3.1 カラー画像を使う(※転載対象外)」をご覧ください)。対して赤外線画像は16ビットのグレースケールデータです。これを変換することでTexture2D化しています。16ビットのグレースケールデータそのものは_Dataフィールドに、BGRA32にフォーマットされたデータは_RawDataフィールドにそれぞれ格納されています。
6.3.3 Depthデータを表示する
Depthデータを表示させる手順はこれまでとほぼ同じですが、Unity上での画面表示が異なります。Depthデータは距離なので、Unityのメッシュを使い、飛び出す絵本のように表示してくれます。
Depthデータは距離だけなので、カラー画像を合わせて使うことでカラーの距離画像となっています。
この距離画像の作り方を解説します。カラー画像や赤外線画像のように「Cube」を配置します。実際の表示はメッシュで行われるので、パラメーターについては既定のままです。今回はカラーとDepthを使うので、「ColorSourceManager」と「DepthSourceManager」の2つ、または「MultiSourceManager」を設定します。「MultiSourceManager」はKinect SDKの「MultiSourceFrameReader」を使ったクラスで、複数のストリームを同期して取得します。ここでは「MultiSourceManager」を使っています。
「Cube」に「MultiSourceManager」と「DepthSourceView」を配置します。
「DepthSourceView」の「Multi Source Manager」に「Cube」を設定し、「View Mode」を「Multi Source Reader」に設定します。もう一つの「Separate Source Reader」は「ColorSource Manager」と「DepthSourceManager」を個別に設定した場合に選択します。
実行するとカラーの距離画像が表示されます。
矢印キーで上下左右に動かすことができます。
Depthデータは、「DepthSourceManager」ではGetData()メソッドで、「MultiSourceManager」ではGetDepthData()メソッドで、ushortの配列として取得できます。「DepthSourceView」では、このDepthデータをもとにメッシュを作成して表示しています。
6.3.4 Bodyを表示する
続いてBodyを表示させてみます。BodyはCubeなどに描画されるのではなく、「BodySourceView」内で新しいGameObjectを生成しています。
BodySourceManagerおよびBodySourceViewを動作させる空のGameObjectを配置します。「Hierarchy」の「Create」から「Create Empty」を選択して、空のGameObjectを配置します。パラメーターについては既定のままです。
ここに「BodySourceManager」と「BodySourceView」のスクリプトを設定します。
「Body Source View」にある「Bone Material」に対して、「Project」ビューの「KinectView|Materials|BoneMaterial」を設定します。
続いて「Body Source Manager」にGameObject(新しく追加したもの)を設定します。
以上で設定は完了です。実行すると、Kinectが認識した人の関節が表示されます。
BodyのデータをKinectから取得するのは「BodySourceManager」です。ここにGetData()というメソッドがあり、Bodyの配列を返します。Bodyの詳細な解説については、「3.5 体(骨格)の検出を行う(※転載対象外)」を参照してください。
BodySourceViewでは新しいGameObjectを作成し、その子要素としてBodyから取得できる位置情報をもとに、各関節のGameObjectを作成しています。
■
次回は、UnityでKinectを使う際にポイントとなる、Kinectの座標系とUnityの座標系を合わせる方法を、実際のサンプルコードを通して説明します。
※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
1. Kinect開発者のための、Unityの基礎知識とインストール
UnityでKinectを活用しよう。Unityのインストール方法と、Kinectを使うためのパッケージの導入方法、Visual Studio Tools for Unityの概要を解説する。
2. 【現在、表示中】≫ UnityでKinectを使う(カラー画像/赤外線画像/Depthデータ/Body)
Unity+Kinectの開発環境が整ったら、実際にUnityからKinectの機能を使ってみよう。UnityによるKinect活用の基礎を解説。
3. Kinectの座標とUnityの座標を合わせる
UnityでKinectを使う際にポイントとなる、Kinectの座標系とUnityの座標系を合わせる方法を、実際のサンプルコードを通して説明する。
5. Kinect WPF ControlsでWPFアプリでもジェスチャーを活用しよう
WPFアプリにKinectを操作するための機能を実装する場合にはKinect WPF Controlsが便利だ。その機能概要を紹介する。