Kinectでヘッドトラッキング

LookingGlass欲しいけど高い!!

openCVとかで頭の位置を取得して、自分の立ち位置でカメラを動かせたら

擬似的なLookingGlassできないかなーと思っていた。

 

 

10年以上前に既にあった。

 

 

で、最近かなりお世話になっているよしなが先生のサイトからリンク先を漁りました。

 

https://speakerdeck.com/takashiyoshinaga/kinectwoyong-itahetudotoratukingu

 

基本的にはUnityのKinectSDKを入れて

Cameraに「KinectManager」スクリプトをアタッチ。

Kinectの取得した頭情報=カメラの動きにするスクリプトをひとつ作るだけで出来る。

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HeadGetScript : MonoBehaviour{

    void Update() {

        KinectManager kinect = KinectManager.Instance;
        if(kinect != null){
            uint playerID = kinect.GetPlayer1ID();
            if(playerID > 0){//人が認識されていれば
                Vector3 head = kinect.GetJointPosition(playerID,3);//3は頭
                head.Set(head.x, head.y , -head.z);//Z位置だけ反転させる
                 Camera.main.transform.position=head;
            }
         }
    }

}

 

このスクリプトをカメラにアタッチすればOK

 

ただし、綺麗に見せるためにはカメラや描画を座標変換する必要がある

https://docs.unity3d.com/ja/current/ScriptReference/Matrix4x4.html

サイン・・コサイン・・変換行列・・・(´A`)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class HeadGetScript : MonoBehaviour{
   

    public float halfWidth = 0.3f * 0.5f;//モニターの物理的な幅
    public float halfHeight = 0.32f * 0.5f;//モニターの物理的な高さ

    [Range(0, 1)]
    public float KinectPosition_Y;//キネクトの置いている高さ

    public Camera targetcamera;
        

    void Update(){
        KinectManager kinect = KinectManager.Instance;
        if(kinect != null){
            uint playerID = kinect.GetPlayer1ID();
            if(playerID > 0){//人が認識されていれば
                Debug.Log("認識");
                Vector3 head = kinect.GetJointPosition(playerID,3);//3は頭
                head.Set(head.x, head.y - KinectPosition_Y, -head.z);//Yはキネクトの高さ分位置を減らす、Z位置だけ反転させる
                targetcamera.transform.position=head;

                Matrix4x4 m = PerspectiveOffCenter(
                    -halfWidth - head.x, halfWidth - head.x,//left,right
                    -halfHeight - head.y, halfHeight - head.y,//bottom,top
                    -head.z, -head.z + 1//near, far(スクリーンはz=0にあるため頭との距離がnear)
                    );
                targetcamera.projectionMatrix = m;//結果をカメラに反映

            }
        }
    }


    //CG座標を描画座標に変換
    Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near , float far){

        float x = 2 * near / (right -left);
        float y = 2 * near / (top - bottom);
        float a = (right + left) / (right - left);
        float b = (top + bottom) / (top - bottom);
        float c = -(far + near)/(far - near);
        float d = -(2 * far * near) / (far - near);
        float e = -1;

        Matrix4x4 m = new Matrix4x4();

        m[0,0] = x;
        m[0,1] = 0;
        m[0,2] = a;
        m[0,3] = 0;
        m[1,0] = 0;
        m[1,1] = y;
        m[1,2] = b;
        m[1,3] = 0;
        m[2,0] = 0;
        m[2,1] = 0;
        m[2,2] = c;
        m[2,3] = d;
        m[3,0] = 0;
        m[3,1] = 0;
        m[3,2] = e;
        m[3,3] = 0;

        return m;
    }



}

 

 

プロパティ側で色々いじれるように修正して

前回つくったleapmotionに組み込みます。

 

 

ついでにカメラ(自分)を見るようにするために

「Head Look Controller」という便利なアセットを入れました。

https://assetstore.unity.com/packages/tools/animation/head-look-controller-4

 

参考:http://gryith.com/oculus_unity_hlc/
参考:上半身だけうごかす

Head Look Controllerスクリプトはターゲットの座標を追うようになっているため
ターゲットを指定できるように修正してキャラクターにアタッチするだけ。
モデルによってどこのボーンを割り当てるかが違うのでちょっと迷った。

 

完成したものがこちら

部屋が汚くてモニターアップぎみ。

大きなモニターだったらハエるかもしれない。

 

 

realsenceの あの小型感好きだからkinectから乗り換えたい欲。

 

関連記事




コメントを残す

※コメントは承認後に表示されます。
 コメントを公開されたくない場合、名前の後に「:非公開」とつけてください。