Azure Kinectで非接触型のインタラクティブコンテンツを考える
はじめに
コロナ禍において、デジタルサイネージ等のインタラクティブコンテンツ制作は、タッチパネル操作などの接触型ではなく、非接触での操作を考えていく必要がありそうです。そこで、Azure Kinectを使って身体の動きによって画面操作する方法を紹介します。
- Azure Kinectとは
洗練されたコンピュータービジョンと音声モデル、高度な AI センサー、Azure Cognitive Servicesに接続できるさまざまな強力なSDKを備えた、最先端の空間コンピューティング開発者キットです。
動作デモ
Azure Kinectを利用して、以下のような非接触型の操作を考えました。
Handの動きとUIカーソルの連動
マウス操作の代わりを、手の動きで行えるようにします。
- カーソル操作 -> Handの動きに追従
- ボタンをクリックして決定 -> ボタンに一定時間カーソルを合わせたら決定
<デモ動画>
Hand Upジェスチャー
表示画像を切り替えるを、手を挙げる操作で行えるようにします。
- 右手を挙げると次の画像
- 左手を挙げると前の画像
<デモ動画>
Swipeジェスチャー
表示画像を切り替えるを、手を横に振る(スワイプする)動作で行えるようにします。
- 右手を振ると次の画像
- 左手を振ると前の画像
<デモ動画>
Unityでの実装
動作デモで利用しているAzure KinectのBody TrackingのUnityを使用した実装について説明します。
前提
動作環境
- CPU:第7世代 Core i5 クアッドコア 2.4GHz 以上
- メモリ:4GB 以上
- GPU:NVIDIA GeForce GTX 1070 以上推奨
- USB接続:USB 3.x (2.0は不可)
開発環境
- Unity2019.4.x
- Visual Studio 2019
- MicrosoftのGitHub Azure-Kinect-Samples内のUnityプロジェクト sample_unity_bodytracking を利用
UnityでBody Trackingを使用可能にする
sample_unity_bodytrackingプロジェクト直下のREADME.mdの内容を参考に設定を行います。
- get the latest nuget packages of libraries
UnityプロジェクトをVisual Studioで開いて、Microsoft.Azure.Kinect.BodyTrackingのNuGetパッケージをインストールする。 - add these libraries to the Assets/Plugins folder
Packegsフォルダ内の各ファイルをPluginsフォルダにコピーする。 - add these libraries to the sample_unity_bodytracking project root directory that contains the Assets folder
Packegsフォルダ内の各ファイルをプロジェクト直下にコピーする。
2と3は、プロジェクト直下のMoveLibraryFiles.bat
を実行すれば自動で処理できます。
ビルド時にdllファイルをコピーする
以下のファイルをビルドしたフォルダ直下(exeファイルのあるフォルダ)にコピーすることで、exeファイル実行時にAzure Kinectを使用できるようになります。
- cublas64_100.dll
- cudart64_100.dll
- cudnn64_7.dll
- dnn_model.onnx
- onnxruntime.dll
※Body Tracking使用のための設定をした際に、プロジェクト直下にコピーしたものと同じです。
Skeleton情報を取得する
Skeleton(骨格)情報には、階層構造を持つ32の関節(Azure Kinect ボディ トラッキングの関節)の情報が含まれています。
Skeleton情報をC#から取得します。
using Microsoft.Azure.Kinect.Sensor;
using Microsoft.Azure.Kinect.BodyTracking;
using System.Threading.Tasks;
// Kinectの情報を扱う変数
private Device device;
private DeviceConfiguration deviceConfig;
private Tracker tracker;
private TrackerConfiguration trackerConfig;
private Calibration calibration;
private Skeleton kinectSkeleton;
void Start()
{
bool kinectCheck = InitDevice();
if (kinectCheck)
{
Task trackerTask = GetTrackerLoop();
}
}
// Kinectの初期化を行う
private bool InitDevice()
{
bool devideCheck = false;
// 接続されているKinectの数をチェック
int count = Device.GetInstalledCount();
if (count > 0)
{
// 1台目のKinectに接続
try
{
device = Device.Open(0);
}
catch (AzureKinectOpenDeviceException ex)
{
return devideCheck;
}
// 起動
try
{
device.StartCameras(deviceConfig = new DeviceConfiguration
{
ColorFormat = ImageFormat.ColorBGRA32,
ColorResolution = ColorResolution.R720p,
DepthMode = DepthMode.NFOV_Unbinned,
SynchronizedImagesOnly = true,
CameraFPS = FPS.FPS30
});
}
catch (AzureKinectStartCamerasException ex)
{
return devideCheck;
}
// トラッカーを作成する
calibration = device.GetCalibration(deviceConfig.DepthMode, deviceConfig.ColorResolution);
trackerConfig = new TrackerConfiguration();
trackerConfig.ProcessingMode = TrackerProcessingMode.Gpu;
trackerConfig.SensorOrientation = SensorOrientation.Default;
skeletonPoints = new GameObject[(int)JointId.Count - 1];
devideCheck = true;
}
return devideCheck;
}
// 別スレッドでSkeletonを取得
private async Task GetTrackerLoop()
{
using (tracker = Tracker.Create(calibration, trackerConfig))
{
while (true)
{
// Kinectから送られてくるフレームを取得
using (Capture capture = await Task.Run(() =>
device.GetCapture()).ConfigureAwait(true))
{
tracker.EnqueueCapture(capture);
}
using (Frame frame = await Task.Run(() =>
tracker.PopResult(TimeSpan.Zero, throwOnTimeout: false)).ConfigureAwait(true))
{
if (frame != null)
{
if (frame.NumberOfBodies > 0)
{
// 最初にKinectが認識したSkeletonを取得
kinectSkeleton = frame.GetBodySkeleton(0);
}
}
}
}
}
}
取得したSkeleton情報から、今回はHANDのPositionを操作に利用します。
- HAND_LEFT
- HAND_RIGHT
HANDの位置を画面操作に利用する
3次元座標のHANDの位置情報を使って、どうやって2次元座標のスクリーン上のカーソルを動かせばいいのか悩みます。そこで、Azure Kinectで認識している体験者の前に追従する見えないスクリーンがあると考え、仮想スクリーン上のローカル座標のPositionを、UIのスクリーン上のローカル座標のPositionに代入します。
<Unity Editor上の動作>
Skeletonが取得できていれば、モニターの真正面に体験者が立っている必要はなく、多少ズレた位置に立っていてもカーソルの操作ができます。また、ジェスチャー操作は、手を頭より高い位置まで挙げた場合などの条件を設定することで実現できます。
まとめ
Azure Kinectを使用することで簡単に非接触の画面操作が実現できました。今回は簡単な例を試しましたが、Body Trackingによる位置情報やジェスチャーによる操作方法は色々と考えられ、新様式のコンテンツ制作にも合わせることができそうです。