KinectForUnity—— KinectManager源码分析

一、将Kinect和Unity3D联系起来的插件中最核心的就是 KinectManager 脚本。要想在Unity3d 中使用 Kinect ,就需要将KinectManager脚本拖放到场景中的某一个物体上。一般是在该场景中新建一个空物体,将其命名为 KinectController ,然后将一些控制的核心脚本都拖到该物体上,如将 KinectManager 脚本拖放到 KinectController 这个空物体上即可。

1、Unity中的 KinectManager 脚本在 Inspector中所显示的各项。(KinectManager 是一个单例模式)

箭头所指项可以设置玩家被Kinect检测到的条件。如,当设置Size为1时,在Element中可以选择某一姿态。意味着当玩家进入到Kinect视角之中后,当做这个姿态时,就会被Kinect检测到,并被追踪。而其他的玩家即使更早的进入到KInect的视角中,如果没有做出该姿态,仍将不会被检测到。

 


二、KinectManager.cs 脚本文件

1、KinectManager.cs 文件中常用的API

  • KinectManager实例化(222):  public static KinectManager Instance
  • 判断Kinect传感器及组件是否初始化(234):IsKinectInitialized(),IsInitialized()
  • 获取主要用户的ID(第一个或者最靠近的一个人);如果没有检测到用户时,返回0(575):public Int64 GetPrimaryUserID()
  • 重新设置主要用户的ID(585):public bool SetPrimaryUserID(Int64 userId)
  • 获取指定用户的关节点在Kinect中的坐标,距离的单位是米(803):public Vector3 GetJointKinectPosition(Int64 userId, int joint)
  • 获取用户相对于传感器的位置信息(703):public Vector3 GetUserPosition(Int64 userId)
  • 获取指定用户左手的状态(1284):public KinectInterop.HandState GetLeftHandState(Int64 userId)
  • 更新彩色贴图信息(2781):void UpdateColorMap()
  • 获取彩色图片(429):public Texture2D GetUsersClrTex()
  • 更新Kinect数据流(2503):private void UpdateKinectStreams()
  • 把人形的位置图计算出来,只要有人的地方就显示出某一颜色来表示。类似于人物在一张贴图中的分布情况,也可以理解为人物分布图(2868):void UpdateUserHistogramImage(UserMapType userMapType)
  • 更新人物分布图(2801):void UpdateUserMap(UserMapType userMapType)
  • 处理body frame的数据(3014):private void ProcessBodyFrameData()
  • 将符合指定姿态的用户添加进用户列表(3647):protected virtual void CalibrateUser(Int64 userId, int bodyIndex)
  • 将其空间点的坐标转换成深度图的坐标(1545):public Vector2 MapSpacePointToDepthCoords(Vector3 posPoint)
  •  

2、KinectManager.cs 文件中常用的变量

  • sensorData.bodyCount: 在Kinect2.0中是6,指的是Kinect可以检测到的人数
  • bodyData:表示一个人物的数据
  • kinectPos:获取指定用户在Kinect坐标系中的坐标
  • position:指世界坐标

 

3、获取人物关节点信息的流程方法:

(1)、获取人物的ID

(2)、获取关节信息

  • 先判断人物是否被检测到了:KinectManager.Instance.IsUserDetected()
  • 如果检测到了,再判断该人物的关节点是否被检测到:KinectManager.Instance.IsJointTracked(userid,jointType)
  • 如果也被追踪到了,才可以获取位置信息

(3)、获取手势状态

(4)、获取用户信息

void Update () {

        bool isInit = KinectManager.Instance.IsInitialized(); //首先要对设备进行实例化和初始化,之后才能进行后续的操作
        if (isInit)
        {
            if (KinectManager.Instance.IsUserDetected()) //判断是否检测到人物
            {
                long userid = KinectManager.Instance.GetPrimaryUserID();//获取主要用户的ID
                int jointType = (int)KinectInterop.JointType.HandLeft;//获取左手关节点的对应序号

                //当检测到用户时,就获取到用户的位置信息
                Vector3 userPos = KinectManager.Instance.GetUserPosition(userid);
                print("user.x= " + userPos.x + " user.y= " + userPos.y + " user.z=" + userPos.z);

                //判断这个用户的指定关节点是否被追踪到
                if (KinectManager.Instance.IsJointTracked(userid,jointType))
                {
                    /*如果零追踪到,就开始获取主要用户的左手的位置坐标,单位是m
                     * LeftHandKinectPos 的值表示在Kinect坐标系下,其y轴的值是减去了传感器高度:Sensor Height之后的值
                     * LeftHandPos 的值在x,z轴上的和LeftHandKinectPos的相同,不同的是其y轴的值会加上Sensor Height的值,为世界坐标系下的值
                     */
                    Vector3 LeftHandKinectPos = KinectManager.Instance.GetJointKinectPosition(userid,jointType);
                    Vector3 LeftHandPos = KinectManager.Instance.GetJointPosition(userid, jointType);
                    //将左手的坐标打印出来
                    print("左手坐标为:kx=" + LeftHandKinectPos.x + " ky=" + LeftHandKinectPos.y + " kz=" + LeftHandKinectPos.z);
                    print("左手坐标为:x=" + LeftHandKinectPos.x + " y=" + LeftHandKinectPos.y + " z=" + LeftHandKinectPos.z);


                    // 还可以获取用户手的状态,如检测右手的状态
                    KinectInterop.HandState rightHandState= KinectManager.Instance.GetRightHandState(userid);//获取右手的状态
                    if (rightHandState == KinectInterop.HandState.Closed)
                    {
                        print("右手握拳");
                    }else if (rightHandState==KinectInterop.HandState.Open)
                    {
                        print("右手张开");
                    }else if (rightHandState == KinectInterop.HandState.Lasso)
                    {
                        print("yes 手势");
                    }else if (rightHandState == KinectInterop.HandState.Unknown)
                    {
                        print("未知手势");
                    }
                }
            }  
        }

    }

三、各模块源码分析

1、彩色图的源码分析,Kinect如何获取彩色图

 

2、深度图的源码分析:

(1)、流程

  1. 先执行 Awake() 来启动设备
  2. 再执行 StartKinect() 来对设备进行初始化,并读取数据流
  3.  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值