一、将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)、流程
- 先执行 Awake() 来启动设备
- 再执行 StartKinect() 来对设备进行初始化,并读取数据流