はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Kinectを使って身体座標を取得してみる

はじめに

アルバイトにてKinectを使う必要があったので、その基本的な操作であるKinectを使った身体座標の取得を紹介したいと思います。

下準備

こちらの記事が分かりやすくまとめてくださっているので、こちらを参照してみてください。

デモシーンがちゃんと動けばOKです。
qiita.com

身体座標を取得する

デモシーンを用いてもよいですが、より仕組みを分かりやすくするために新規シーンから身体座標を取得してみたいと思います。

下準備にて入れた.unitypackageの中にBody Source Managerというスクリプトが存在するはずです。

このスクリプトを用いることでKinectの起動 -> Kinectが検出した身体情報を取得 -> Kinectを終了する(アプリ終了時)までを扱うことができます。

ゲームオブジェクトを新規作成してBody Source Managerをアタッチしてみてください。

f:id:hanaaaaaachiru:20200511221617p:plain

このコンポーネントを利用するためにC#スクリプトを作成し、ゲームオブジェクトにアタッチしてみます。

using UnityEngine;
using Windows.Kinect;

public class Test : MonoBehaviour
{
    [SerializeField]private BodySourceManager _manager;

    private void Update()
    {
        // そもそも参照が取れていないときはダメ
        if (_manager == null) return;

        // ここで人の身体情報の配列(つまりは複数人の身体座標)を受け取る
        var bodies = _manager.GetData();

        if (bodies == null) return;

        // 複数人から一人一人の身体情報を取り出す
        foreach (var body in bodies)
        {
            if (body == null) continue;
            if (body.IsTracked == false) continue;

            // 特定の部位の座標の取り出し方
            Debug.Log($"Right Hand Position : {body.Joints[JointType.HandRight].ToVector3()}");

            // 右手が開いているかどうか
            Debug.Log($"Right Hand State: {body.HandRightState.ToString()}");
        }

    }
}

public static class JointExtensions
{
    public static Vector3 ToVector3(this Windows.Kinect.Joint joint)
        => new Vector3(joint.Position.X * 10, joint.Position.Y * 10, joint.Position.Z * 10);
}

もう少し詳しく見ていきましょう。

座標の取り出し方

body.Joints[JointType.HandRight];

このようにすることでJoint構造体を取得することができます。

Joint -> Vector3に変換するにはそれぞれの値を10倍すると大丈夫みたいです。(サンプルにこのように書いてあったのですが、本当にあっているのかはよく分かっていません)

またJointTypeには以下の通りです。

SpineBase                                =0,
SpineMid                                 =1,
Neck                                     =2,
Head                                     =3,
ShoulderLeft                             =4,
ElbowLeft                                =5,
WristLeft                                =6,
HandLeft                                 =7,
ShoulderRight                            =8,
ElbowRight                               =9,
WristRight                               =10,
HandRight                                =11,
HipLeft                                  =12,
KneeLeft                                 =13,
AnkleLeft                                =14,
FootLeft                                 =15,
HipRight                                 =16,
KneeRight                                =17,
AnkleRight                               =18,
FootRight                                =19,
SpineShoulder                            =20,
HandTipLeft                              =21,
ThumbLeft                                =22,
HandTipRight                             =23,
ThumbRight                               =24,

f:id:hanaaaaaachiru:20200511224310p:plain

手の状態を取得する

body.HandRightState

HandRightStateプロパティ(左手ならHandLeftState)からHandStateを取得できます。

Unknown                                  =0,
NotTracked                               =1,
Open                                     =2,
Closed                                   =3,
Lasso                                    =4,

Openは手が開いている状態で、Closedは閉じている状態を指します。

Lassoというのはかなり特殊で「投げ縄」の状態というらしく、じゃんけんのチョキに似ていますが人差し指と中指の先のほうがくっついている状態のようです。

The lasso hand state is a closed hand with the middle and index fingers both up.

Body tracking | Microsoft Docs

なぜこのようになっているのか分かりませんが、欲を言うとチョキが良かった。。。

さいごに

今回は本当に基礎的なところを紹介してみました。

正直ドキュメントがしっかりしているともいえないので、サンプルを見たりコードを読むのが結局一番だと思います。

まだまだ面白い機能がたくさんあるので、時間があれば記事を書くかもしれません。

ではまた。