kinect2.0 unity开发for unity 怎样只能识别一个人的姿势

2881人阅读
Unity(1)
Kinect(1)
前几天环境配好了,连上Kinect能跑示例项目KinectView。花了很大的力气找插件的API手册,原来插件并没有官方手册,目前官网也只有两个示例项目。于是自己看代码,想首先学会怎样写一个手势触发特定事件。主要看了BodySourceManager.cs和BodySourceView.cs,中午成功写出了如果左手高过头顶,自动截屏保存图片。
思路是if判断,如果左手的y坐标值大于等于头顶的y坐标值条件为真,触发事件,调用Unity的一个API叫Application.Capturescreenshot()。在BodySourceView.cs中的RefreshBodyObject()函数中修改,这个函数会在Update()中调用,每一帧都会更新。红框部分是自己添加的代码,其余均为无改动的示例源码。
Kinect.JoinType可以按F12查看插件中的源代码,可知是枚举类型,如图
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & &
简要分析一下示例程序中的RefreshBodyObejct函数。这个函数主要做的是获取关节点坐标,在Unity中画出人体骨骼。画骨骼直接用Unity的线渲染LineRender(在前面代码中已经调用它的SetVertexCount方法设置画得线有两个端点)。遍历Dictionary类型的_Bonemap(保存的是Key-Value键值对,Value是Key的下一个关联结点),key就是画线段的源位置,value就是线段的目标位置。
完整代码如下
BodySourceManager.cs
using UnityE
using System.C
using Windows.K
public class BodySourceManager : MonoBehaviour
private KinectSensor _S
private BodyFrameReader _R
private Body[] _Data =
public Body[] GetData()
void Start ()
_Sensor = KinectSensor.GetDefault();
if (_Sensor != null)
_Reader = _Sensor.BodyFrameSource.OpenReader();
if (!_Sensor.IsOpen)
_Sensor.Open();
void Update ()
if (_Reader != null)
var frame = _Reader.AcquireLatestFrame();
if (frame != null)
if (_Data == null)
_Data = new Body[_Sensor.BodyFrameSource.BodyCount];
frame.GetAndRefreshBodyData(_Data);
frame.Dispose();
void OnApplicationQuit()
if (_Reader != null)
_Reader.Dispose();
if (_Sensor != null)
if (_Sensor.IsOpen)
_Sensor.Close();
&pre name=&code& class=&csharp&&BodySourceView.cs
using UnityE
using System.C
using System.Collections.G
using Kinect = Windows.K
public class BodySourceView : MonoBehaviour
public Material BoneM
public GameObject BodySourceM
private Dictionary&ulong, GameObject& _Bodies = new Dictionary&ulong, GameObject&();
private BodySourceManager _BodyM
private Dictionary&Kinect.JointType, Kinect.JointType& _BoneMap = new Dictionary&Kinect.JointType, Kinect.JointType&()
{ Kinect.JointType.FootLeft, Kinect.JointType.AnkleLeft },
{ Kinect.JointType.AnkleLeft, Kinect.JointType.KneeLeft },
{ Kinect.JointType.KneeLeft, Kinect.JointType.HipLeft },
{ Kinect.JointType.HipLeft, Kinect.JointType.SpineBase },
{ Kinect.JointType.FootRight, Kinect.JointType.AnkleRight },
{ Kinect.JointType.AnkleRight, Kinect.JointType.KneeRight },
{ Kinect.JointType.KneeRight, Kinect.JointType.HipRight },
{ Kinect.JointType.HipRight, Kinect.JointType.SpineBase },
{ Kinect.JointType.HandTipLeft, Kinect.JointType.HandLeft },
{ Kinect.JointType.ThumbLeft, Kinect.JointType.HandLeft },
{ Kinect.JointType.HandLeft, Kinect.JointType.WristLeft },
{ Kinect.JointType.WristLeft, Kinect.JointType.ElbowLeft },
{ Kinect.JointType.ElbowLeft, Kinect.JointType.ShoulderLeft },
{ Kinect.JointType.ShoulderLeft, Kinect.JointType.SpineShoulder },
{ Kinect.JointType.HandTipRight, Kinect.JointType.HandRight },
{ Kinect.JointType.ThumbRight, Kinect.JointType.HandRight },
{ Kinect.JointType.HandRight, Kinect.JointType.WristRight },
{ Kinect.JointType.WristRight, Kinect.JointType.ElbowRight },
{ Kinect.JointType.ElbowRight, Kinect.JointType.ShoulderRight },
{ Kinect.JointType.ShoulderRight, Kinect.JointType.SpineShoulder },
{ Kinect.JointType.SpineBase, Kinect.JointType.SpineMid },
{ Kinect.JointType.SpineMid, Kinect.JointType.SpineShoulder },
{ Kinect.JointType.SpineShoulder, Kinect.JointType.Neck },
{ Kinect.JointType.Neck, Kinect.JointType.Head },
void Update ()
if (BodySourceManager == null)
_BodyManager = BodySourceManager.GetComponent&BodySourceManager&();
if (_BodyManager == null)
Kinect.Body[] data = _BodyManager.GetData();//GetData();
if (data == null)
List&ulong& trackedIds = new List&ulong&();
foreach(var body in data)
if (body == null)
if(body.IsTracked)
trackedIds.Add (body.TrackingId);
List&ulong& knownIds = new List&ulong&(_Bodies.Keys);
// First delete untracked bodies
foreach(ulong trackingId in knownIds)
if(!trackedIds.Contains(trackingId))//List方法测试一个元素是否在List内
Destroy(_Bodies[trackingId]);//先Destroy掉GameObject
_Bodies.Remove(trackingId);//再将键值对从_Bodies字典中移除
foreach(var body in data)
if (body == null)
if(body.IsTracked)
if(!_Bodies.ContainsKey(body.TrackingId))
_Bodies[body.TrackingId] = CreateBodyObject(body.TrackingId);
RefreshBodyObject(body, _Bodies[body.TrackingId]);
private GameObject CreateBodyObject(ulong id)
GameObject body = new GameObject(&Body:& + id);
for (Kinect.JointType jt = Kinect.JointType.SpineB jt &= Kinect.JointType.ThumbR jt++)
GameObject jointObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
LineRenderer lr = jointObj.AddComponent&LineRenderer&();
lr.SetVertexCount(2);//设置线段数
lr.material = BoneM//物体的材质
lr.SetWidth(0.05f, 0.05f);//设置线的开始和结束宽度
jointObj.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
jointObj.name = jt.ToString();
jointObj.transform.parent = body.
private void RefreshBodyObject(Kinect.Body body, GameObject bodyObject)
for (Kinect.JointType jt = Kinect.JointType.SpineB jt &= Kinect.JointType.ThumbR jt++)
Kinect.Joint sourceJoint = body.Joints[jt];
Kinect.Joint? targetJoint =
if(_BoneMap.ContainsKey(jt))
targetJoint = body.Joints[_BoneMap[jt]];//所以之前字典中设置就是一个一个关节连起来
Transform jointObj = bodyObject.transform.FindChild(jt.ToString());
jointObj.localPosition = GetVector3FromJoint(sourceJoint);
LineRenderer lr = jointObj.GetComponent&LineRenderer&();
if(targetJoint.HasValue)
//Debug.Log (jointObj.localPosition);ok
lr.SetPosition(0, jointObj.localPosition);
lr.SetPosition(1, GetVector3FromJoint(targetJoint.Value));
lr.SetColors(GetColorForState (sourceJoint.TrackingState), GetColorForState(targetJoint.Value.TrackingState));
lr.enabled =
if(body.Joints[Kinect.JointType.HandLeft].Position.Y&=body.Joints[Kinect.JointType.Head].Position.Y){
Debug.Log(&handleft:&+body.Joints[Kinect.JointType.HandLeft].Position.Y);
Debug.Log(&head:&+body.Joints[Kinect.JointType.Head].Position.Y);
Debug.Log(&My LeftHand is Higher than head!~&);
Application.CaptureScreenshot (&Screenshoot.png&, 0);
private static Color GetColorForState(Kinect.TrackingState state)
switch (state)
case Kinect.TrackingState.Tracked:
return Color.
case Kinect.TrackingState.Inferred:
return Color.
return Color.
private static Vector3 GetVector3FromJoint(Kinect.Joint joint)
return new Vector3(joint.Position.X * 10, joint.Position.Y * 10, joint.Position.Z * 10);
自己琢磨代码还是很开心的,代码值得完整的分析在此不赘述了。写博文是有点折腾,但是今天看到别人的技术博客和心得分享真的是很励志(/ &http://blog.csdn.net/the_fire?viewmode=list)。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6331次
排名:千里之外Kinect2.0&for&Unity---深度帧(4)
GetAvg函数通过某一点的xy坐标,以及分辨率大小,求得该点在depthData中的序号,从而得到该点的深度值,求取序号的公式为Index=y*width+x,是一个二维数组元素重新排列成一维数组的过程,该公式上文提到的函数中也有提及,具体排列方式参考上文:
根据读取到的深度数据,顶点的xy坐标,当前帧数据的宽度和高度,计算出该点在depthData中的序号,从而得到该点的深度值
depthData"&读取到的深度数据
x"&顶点的x坐标
y"&顶点的y坐标
width"&当前帧数据的宽度
height"&当前帧数据的高度
顶点的z坐标
GetAvg(ushort[]
depthData,
sum = 0.0;
y1 = y1 & y + 4; y1++)
&&&&&&&&&&&
x1 = x1 & x + 4; x1++)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
fullIndex = (y1 * width) + x1;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
(depthData[fullIndex] == 0)//表示超出范围
&&&&&&&&&&&&&&&&&&&
sum += 4500;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
sum += depthData[fullIndex];
&&&&&&&&&&&&&&&
&&&&&&&&&&&
附:三角形顶点数为6*(width-1)*(height-1)的推导过程:
一个3行4列的点阵组成的矩形,能够分割成6个小矩形,每一行每一列除去左右2个端点后剩下的点的个数即为可以切开的次数,切成的小矩形的个数即为切开次数+1,因此,对于一个x行y列的点阵,可以看做由[(x-2)+1]*[(y-2)+1]个最小单元矩形组成,即一共为(x-1)*(y-1)个单元矩形,对于每一个单元矩形而言,可以分成两个三角形,对于每一个三角形而言,共有3个顶点,因此,三角形的顶点总数为(x-1)*(y-1)*2*3,即6*(width-1)*(height-1)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(398ffbbc-ua98).
重新安装浏览器,或使用别的浏览器基于unity的kinect多人识别方法? - 知乎4被浏览304分享邀请回答0添加评论分享收藏感谢收起2687人阅读
Unity3D(21)
Kinect2.0(5)
using UnityE
using System.C
using UnityEngine.UI;
public class UseOverKinectManager : MonoBehaviour {
public RawImage kinectI
public Image rightH
public Image btn1;
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
bool isInit = KinectManager.Instance.IsInitialized();
//检测设备可用
if (isInit) {
// print(&width = & + KinectManager.Instance.GetDepthImageWidth() + & height = & + KinectManager.Instance.GetDepthImageHeight()); //宽高
//设备准备好了
可以读取了
if (kinectImg.texture == null)
Texture2D kinectPic = KinectManager.Instance.GetUsersClrTex();
//从设备获取彩色数据
// Texture2D kinectPic = KinectManager.Instance.GetUsersLblTex();
//获取深度数据量
kinectImg.texture = kinectP
//把彩色数据给控件显示
if (KinectManager.Instance.IsUserDetected())
//检测到玩家
long userId = KinectManager.Instance.GetPrimaryUserID();
//获取用户id
int jointType = (int)KinectInterop.JointType.HandR
if (KinectManager.Instance.IsJointTracked(userId,jointType))
//关节点被追踪到
Vector3 rightHandPos = KinectManager.Instance.GetJointKinectPosition(userId, jointType);
//1.获取关节点3D坐标
Vector3 rightHandScreenPos = Camera.main.WorldToScreenPoint(rightHandPos);
//2.关节点坐标转换成屏幕坐标
Vector2 rightHandSenPos = new Vector2(rightHandScreenPos.x, rightHandScreenPos.y);
// print(&x = & + rightHandScreenPos.x + & y = & + rightHandScreenPos.y);
Vector2 rightHandUguiP
if(RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform, rightHandSenPos, null,out rightHandUguiPos))
//表示右手在矩形范围内
RectTransform rightRectTf =
rightHand.transform as RectT
rightRectTf.anchoredPosition = rightHandUguiP
if (RectTransformUtility.RectangleContainsScreenPoint(btn1.rectTransform,rightHandSenPos,null))
//手在按钮1上悬停
// print(&手在按钮1上悬停&);
KinectInterop.HandState rightHandState = KinectManager.Instance.GetRightHandState(userId);
if (rightHandState == KinectInterop.HandState.Closed)
//print(&握拳选择了&);
// print(&离开&);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:325575次
积分:3350
积分:3350
排名:第10235名
原创:87篇
转载:12篇
评论:22条
(1)(2)(2)(3)(2)(4)(2)(5)(5)(7)(10)(9)(1)(3)(1)(2)(1)(1)(1)(1)(1)(2)(2)(1)(2)(1)(1)(3)(1)(12)(2)(4)(1)(2)(1)

我要回帖

更多关于 kinect2.0 unity 的文章

 

随机推荐