UnityでKinect v2を利用する

はじめに

UnityでKinect v2を利用するメモ
画像を出したりだとかはいっぱいサンプルあるので単純に人を検出するだけのシンプルなコード

バージョン

  • Unity 5.3
  • Kinect v2 2.0.1410

必要なライブラリ

Kinect v2のSDK( https://www.microsoft.com/en-us/download/confirmation.aspx?id=44561 )を入れた上で
http://download.microsoft.com/download/F/8/1/F81BC66F-7AA8-4FE4-8317-26A0991162E9/KinectForWindows_UnityPro_2.0.1410.zip
からUnity用のパッケージを落とす

Kinect.2.0.1410.19000.unitypackageをインポートして全部入れる

ソース

起動と終了時の処理

最低限のコードだけならこんな感じ

Kinect.cs

 1using UnityEngine;
 2using System.Collections;
 3using System.Collections.Generic;
 4
 5using Windows.Kinect;
 6
 7public class Kinect : MonoBehaviour {
 8    KinectSensor _Sensor;
 9    BodyFrameReader _Reader;
10    Body[] _Data = null;
11
12    void Start () {
13        _Sensor = KinectSensor.GetDefault();
14        if (_Sensor != null){
15            _Reader = _Sensor.BodyFrameSource.OpenReader();
16            if (!_Sensor.IsOpen){
17                _Sensor.Open();
18            }
19        }
20    }
21
22    void OnApplicationQuit(){
23        if (_Reader != null){
24            _Reader.Dispose();
25            _Reader = null;
26        }
27        if (_Sensor != null){
28            if (_Sensor.IsOpen){
29                _Sensor.Close();
30            }
31            _Sensor = null;
32        }
33    }
34}

フレームの取得

必ずDisposeメソッドを呼ぶこと
呼び忘れると初回以降AcquireLatestFrameメソッド呼ぶとひたすらnullが帰されて悲しいことになる
AcquireLatestFrameは結構null返ってくるから他の方法で実装出来るらしいからそっちの方が良いかも
体感3回に1回くらいはnullな感じする

1void Update(){
2    var frame = _Reader.AcquireLatestFrame();
3    if (frame == null){
4        return;
5    }
6    frame.Dispose();
7    frame = null;
8}

人間の検知

 1void Update(){
 2    var frame = _Reader.AcquireLatestFrame();
 3    if (frame == null){
 4        return;
 5    }
 6    if (_Data == null){
 7        _Data = new Body[_Sensor.BodyFrameSource.BodyCount];
 8    }
 9    frame.GetAndRefreshBodyData(_Data);
10    frame.Dispose();
11    frame = null;
12
13    if (_Data == null){
14        return;
15    }
16
17    foreach(var body in data){
18        if (body == null) {
19            continue;
20        }
21        if (body.IsTracked){
22            Debug.Log("人がいるよ!");
23            // RefreshBodyObject(body);
24        }
25    }
26}

ボーンの取得

色々大変

 1static Vector3 GetVector3FromJoint(Windows.Kinect.Joint joint) {
 2    return new Vector3(joint.Position.X * 10, joint.Position.Y * 10, joint.Position.Z * 10);
 3}
 4
 5void RefreshBodyObject(Windows.Kinect.Body body){
 6    for (Windows.Kinect.JointType jt = Windows.Kinect.JointType.SpineBase; jt <= Windows.Kinect.JointType.ThumbRight; jt++) {
 7        Windows.Kinect.Joint sourceJoint = body.Joints[jt];
 8        Vector3 tmp = GetVector3FromJoint(sourceJoint);
 9        Debug.Log("name:"+jt);
10        Debug.Log("x:"+tmp[0]);
11        Debug.Log("y:"+tmp[1]);
12        Debug.Log("z:"+tmp[2]);
13    }
14}

あとは煮るなり焼くなりお好きに
長い