您的位置:首页 > 其它

Kinect for windows 开发入门 九:骨骼数据获取和使用

2013-08-22 20:20 344 查看
背景知识

1.  骨骼追踪:骨骼追踪技术通过处理景深数据来建立人体各个关节的坐标,骨骼追踪能够确定人体的各个部分,如那部分是手,头部,以及身体。在Kinect里面,是通过20个关节点来表示一个骨架的,具体由下图可以看到。当你走进Kinect的视野范围的时候,Kinect就可以把你的20个关节点的位置找到(当然你得站着),位置通过(x,
y, z)坐标来表示。SkeletonStream产生的每一帧数据都是一个骨骼对象集合。每一个骨骼对象包含有描述骨骼位置以及骨骼关节的数据。每一个关节有一个唯一标示符如头(head)、肩(shoulder)、肘(dlbow)等信息和3D向量数据。



2.  关节坐标:玩家的各关节点位置用(x, y, z)坐标表示。与深度图像空间坐标不同的是,这些坐标单位是米。坐标轴x,y,z是深度感应器实体的空间x, y, z坐标轴。这个坐标系是右手螺旋的,Kinect感应器处于原点上,z坐标轴则与Kinect感应的朝向一致。y轴正半轴向上延伸,x轴正半轴(从Kinect感应器的视角来看)向左延伸,如下图所示。为了方便讨论,我们称这些坐标的表述为关节坐标。如图所示,每个轴的取值都是有范围的。需要注意的是,这里的Y轴不一定是与地面垂直的。



 

3.  Kinect一代最多可以跟踪两个骨骼,可以最多检测六个人(仅位置)。站立模式可以跟踪20个关节点,坐着的模式的话,可以跟踪10个关节点。二代有所改进,可以跟踪7个人的骨骼。

4.  Kinect能够追踪到的骨骼数量是一个常量。这使得我们在整个应用程序中能够一次性的为数组分配内存。

5.  通过Kinect获取的每一帧skeletonFrame有好与不好之分。你的姿势、是否有阻挡等等情况,都会影响跟踪的质量。所以在处理之前需要判断一下是否是一个追踪好的骨骼,可以使用Skeleton对象的TrackingState属性来判断,只有骨骼追踪引擎追踪到的骨骼我们才进行处理,忽略哪些不是游戏者的骨骼信息即过滤掉那些TrackingState不等于SkeletonTrackingState.Tracked的骨骼数据。

6. 深度数据或者影像数据用像素来表示,X,Y位置从左上角以0开始。深度数据的Z方位数据以毫米为单位。

代码演示

1.  获取节点位置信息

           using (SkeletonFrame
frame =e.OpenSkeletonFrame())

            {

                if (frame ==null)

                {

                    return;

                }

               frame.CopySkeletonDataTo(this.frameSkeletons);

                foreach (Skeleton
skeleton inthis.frameSkeletons)

                {

                    if (skeleton.TrackingState ==SkeletonTrackingState.Tracked)

                   {

                       SetEllipsePostion(headEllipse, skeleton.Joints[JointType.Head].Position);

                       SetEllipsePostion(handLeftEllipse, skeleton.Joints[JointType.HandLeft].Position);

                        SetEllipsePostion(handRightEllipse,skeleton.Joints[JointType.HandRight].Position);

                       SetEllipsePostion(footLeftEllipse, skeleton.Joints[JointType.FootLeft].Position);

                       SetEllipsePostion(footRightEllipse, skeleton.Joints[JointType.FootRight].Position);

                       SetEllipsePostion(hipCenterElipse, skeleton.Joints[JointType.HipCenter].Position);

                   }

                }

            }

2.  显示节点位置

       privatevoid SetEllipsePostion(FrameworkElementellipse,SkeletonPoint
skeletonPoint)

        {

            DepthImagePoint point =this.Kinect.MapSkeletonPointToDepth(skeletonPoint,this.Kinect.DepthStream.Format);

            point.X= (int)((double)point.X
* this.LayoutRoot.ActualWidth /this.Kinect.DepthStream.FrameWidth);

            point.Y= (int)((double)point.Y
* this.LayoutRoot.ActualHeight /this.Kinect.DepthStream.FrameHeight);

            Canvas.SetLeft(ellipse,point.X);

            Canvas.SetTop(ellipse, point.Y);

        }

 

效果演示

1.  节点捕获

如图显示了上面代码所写的六个节点。



      全身重要节点



 

越来越好玩了。下集做个游戏吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: