Deep Tech. Blog

ガジェットや技術についての紹介や自身のメモとして記事を書いていくブログ

【Azure Kinect】自分のポーズに合わせてUnity上のキャラクタを動かしたい(直接的Unity連携編)

目次

Azure Kinectで計測したポーズを基にUnity上のキャラクタを動かしたい

夏季休暇の暇つぶしとしてAzure Kinectを購入したので,そのAzure Kinectで自分のポーズを計測し,更にそのポーズを基にUnity上のCGキャラクタを動かしてみようと思います.

※この分野は素人のため書いてあることに間違いが含まれる可能性があります

Azure Kinectでは後述の事前準備に挙げているようなSDKをインストールすることで,デプス画像からBody trackingを行なうサンプルプログラムが利用できます.そのサンプルプログラムを読めばBody tracking APIからのポーズ情報取得方法は分かると思います.
そして,Unity上で計測したポーズ(人体のジョイント情報群)をCGキャラクタに反映させることで目標を実現出来るのではないかという目論みです.

上記を実現するための方法にはざっくり下記の二通りの方法がありそうです.

  • 方法1. Unity内部で直接Body tracking APIを呼び出してポーズを利用する方法
    • メリット
      • 余計な通信処理が必要ない
      • プログラムの構成がシンプル
    • デメリット
      • 取得したポーズに別の処理を行なうためにC++コードにデータを渡す際にオーバーヘッドが発生
  • 方法2. Body tracking APIを呼び出してポーズを取得しUnityに送信するプログラムとUnityでそのポーズを受信して利用する方法
    • メリット
      • ポーズ取得側プログラムで様々な高速処理を実装が容易
    • デメリット
      • プログラムの構成が複雑
      • 通信によるオーバーヘッドが発生

今回やりたいことからすると方法1がシンプルで容易かと思います.別途認識処理等をポーズを基にしたい場合には方法2の方がいいかも知れません.
本記事ではまず方法1で実装してみようと思います.その後,別記事で方法2の実装を行なってみる予定です.

Microsoft Azure Kinect DK

Microsoft Azure Kinect DK

  • メディア: エレクトロニクス

事前準備

MicrosoftのSample Unity Body Tracking Applicationを導入

有り難いことにMicrosoftGithubにUnity内部でAzure KinectのBody tracking APIを呼び出すサンプルプログラムを公開してくれています.

Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking at master · microsoft/Azure-Kinect-Samples · GitHub

まずはこのサンプルプログラムの動作可能な状態にします.

  1. Githubからサンプルプログラムをダウンロード

    こちらサンプルプログラムをダウンロードします.Gitでクローンしてもいいですが,下図のようにZIPをダウンロードしてもいいです.

    f:id:deep_tech:20200812131536p:plain
    Githubからサンプルプログラムをダウンロード

  2. Unityでサンプルプロジェクトを開く

    ダウンロードしたサンプルプログラム中の/Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking/フォルダをUnityプロジェクトとして開く.
    プロジェクトを新しいバージョンにアップグレードする旨のダイアログボックスが表示されたら確認ボタンを押す.
    Asset Database Version Upgradeダイアログボックスが表示されたYesボタンを押す.

    f:id:deep_tech:20200812194322p:plain
    Unity初回起動画面

  3. UnityとVisual Studioの連携設定

    UnityのEditメニュー => Preference => External Script EditorVisual Studioを設定する.

  4. UnityのScriptをVisual Studioで開く

    UnityのProjectパネル中からどれでもいいのでScriptを開く.Visual Studioが起動し,プロジェクトフォルダにVisual StudioのSolutionファイルが生成されたことを確認する.一旦Visual Studioを終了する.

    f:id:deep_tech:20200812194329p:plain
    Visual Studio初回起動画面

  5. Visual StudioのSolutionファイルを開く

    上記手順で生成されたSolutionファイルをVisual Studioで開き,プロジェクトフォルダ内Packageフォルダに各種依存パッケージがあることを確認する.

    f:id:deep_tech:20200812194342p:plain
    Package一覧

  6. プロジェクトフォルダ中のAssets/Pluginsフォルダにパッケージファイルをコピー

    まず,/Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking/Assets/Pluginsフォルダを作成します.
    作成したPluginsフォルダに下記ファイルをコピーします.

    • Packages/Microsoft.Azure.Kinect.BodyTracking.1.0.1/lib/netstandard2.0フォルダ中の下記ファイルをコピー
    • Packages/Microsoft.Azure.Kinect.Sensor.1.3.0/lib/netstandard2.0フォルダ中の下記ファイルをコピー
    • Packages/Microsoft.Azure.Kinect.BodyTracking.Dependencies.0.9.1/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • cublas64_100.dll
      • cudart64_100.dll
      • vcomp140.dll
    • Packages/System.Buffers.4.4.0/lib/netstandard2.0フォルダ中の下記ファイルをコピー
      • System.Buffers.dll
    • Packages/System.Memory.4.5.3/lib/netstandard2.0フォルダ中の下記ファイルをコピー
      • System.Memory.dll
    • Packages/System.Reflection.Emit.Lightweight.4.6.0/lib/netstandard2.0フォルダ中の下記ファイルをコピー
      • System.Reflection.Emit.Lightweight.dll
    • Packages/System.Runtime.CompilerServices.Unsafe.4.5.2/lib/netstandard2.0フォルダ中の下記ファイルをコピー
      • System.Runtime.CompilerServices.Unsafe.dll
    • Packages/Microsoft.Azure.Kinect.Sensor.1.3.0/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • depthengine_2_0.dll
      • k4a.dll
      • k4arecord.dll
    • Packages/Microsoft.Azure.Kinect.BodyTracking.1.0.1/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • k4abt.dll
      • onnxruntime.dll

    f:id:deep_tech:20200812201731p:plain
    Pluginsフォルダ

  7. simple_unity_bodytrackingプロジェクトフォルダ直下にパッケージファイルをコピー /Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytrackingフォルダに下記のフォルダをコピーします.

    • Packages/Microsoft.Azure.Kinect.BodyTracking.Dependencies.cuDNN.0.9.1/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • cudnn64_7.dll
    • Packages/Microsoft.Azure.Kinect.BodyTracking.Dependencies.0.9.1/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • cublas64_100.dll
      • cudart64_100.dll
    • Packages/Microsoft.Azure.Kinect.BodyTracking.1.0.1/lib/native/amd64/releaseフォルダ中の下記ファイルをコピー
      • onnxruntime.dll
    • Packages/Microsoft.Azure.Kinect.BodyTracking.1.0.1/contentフォルダ中の下記ファイルをコピー
      • dnn_model_2_0.onnx

    f:id:deep_tech:20200812201738p:plain
    simple_unity_bodytrackingフォルダ

  8. Unityにて/Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking/Scenes/Kinect4AzureSampleSceneを開く

    f:id:deep_tech:20200815172645p:plain
    Kinect4AzureSampleSceneを開いた直後

  9. UnityにてPlayボタンでゲーム実行 Playボタンを押して,Azure Kinectの画角内に人物を捕らえると人体ポーズの計測結果をUnity内に可視化することができます.

ここまでの手順でUnity上でAzure Kinectの人体ポーズの計測結果を利用可能な状態になりました.
次は,計測された人体ポーズに合せてCGキャラクタを動作させてみます.

計測した人体ポーズでCGキャラクタを動かす

以下では,上記Sample Applicationの導入によって計測された人体ポーズとCGキャラクタとを結び付けて,自分のポーズに合せてCGキャラクタを動かせるようにします.

  1. CGキャラクタをUnityにインポート

    Unityにて上記手順で利用していた/Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking/プロジェクトを開き,Asset StoreからUnity-Chan!Modelをダウンロード&インポートする.

  2. ユニティちゃんをシーンに追加

    Projectパネル中のAssets/unity-chan!/Unity-chan! Model/Art/Models/unitychan.fbxをHierarchyパネルにドラッグ&ドロップしてユニティちゃんの3Dモデル等一式をシーンに追加する.ここでシーンは保存しておく.

    f:id:deep_tech:20200816190112p:plain
    シーンに追加されたユニティちゃん

  3. ユニティちゃんのリグ設定を確認

    Assets/unity-chan!/Unity-chan! Model/Art/Models/unitychan.fbxを選択し,InspectorパネルのRigタブを選択すると,下図のような画面が表示されます.Animation TypeはHumanoidになっているはずです.このHumanoidタイプで定義されたジョイントとユニティちゃんのモデルがどのように対応しているのかを確認しておきます.

    f:id:deep_tech:20200816185345p:plain
    ユニティちゃんのリグ設定

    Rigタブ中にConfigure...ボタンがあるはずなのでそれを押すと,更に下図のような画面が表示されます.例えばHumanoidタイプのジョイントとして定義されているHips部位には,ユニティちゃんモデル中のCharacter1_Hips Transformationが対応することが分かります.要はこれらのHumanoidタイプのジョイントに計測した人体ポーズのジョイント情報を与えることで,ユニティちゃんを動かせます.

    f:id:deep_tech:20200816185609p:plain
    ユニティちゃんのリグ

  4. HumanoidタイプのRigに計測データを適用

    Rigに計測データを適用するためのサンプルコードは実は/Azure-Kinect-Samples/body-tracking-samples/sample_unity_bodytracking/プロジェクトに含まれています.本来は,Assets/Scenes/PuppetMaster.unityシーンで利用されているはずのコードのようなのですが,このシーンは開いても正しく動きません(2020年8月16日現在).
    そのサンプルコードAssets/Scripts/PuppetAvatar.csを上記手順2でシーンに追加したユニティちゃんモデルにアタッチします.そして,下図のInspectorと同様に,Puppet AvatarスクリプトKinect Device,Root Position,Character Root Transformation,Offset Y, Offset Xを指定します.

    f:id:deep_tech:20200816190141p:plain
    ユニティちゃんへのスクリプト設定

  5. Playボタンで実行

    Playボタンでゲームを実行すると下のビデオのようにユニティちゃんを動かすことができます.棒人間が同時に表示されていると見辛いので,pointBodyオブジェクトは無効化してあります.
    人体ポーズが計測されるまでは変な状態でユニティちゃんが表示されますが,計測が行なわれるとユニティちゃんがポーズに合せて動きます.このユニティちゃんはスクリプトに指定したRoot Positionから動くことができないため,足を曲げてもunitychanのPositionから動くことができず,下の動画中の両膝を挙げるような動きになっていしまっています.このあたりはIKを使って解決する必要がありそうです.その他,紙の動きがおかしいとか全体にピクピクしてるとか,このままでは実用的に使えない気がしますが,今後解決方法など試してみようと思います.

まとめ

Azure Kinectで計測したポーズを基にUnity上のCGキャラクタを動かしてみました.本記事の方法ではサンプルを利用するだけでやりたいことを実現出来てしまいました.この手のCGキャラクタを動かす例題としてはとっつきやすいのではないかと思います.
しかし,このままでは利用できる用途がかなり限られてしまうので,より自然に仮想空間に適合してCGキャラクタを動かすような仕組みを導入する必要がありそうです.