Kinect SDK 正式版(二)骨骼追踪,实现PC版体感水果忍者

    这篇来介绍一下几个正式版SDK提供的新特性,还有比较被主流应用的骨骼数据操作。

    首先先介绍一个新特性,Kinect角度调整,继续上篇的项目工程,在界面上添加两个控件,一个下拉列表,一个按钮。

<Button Content="角度调整" Height="23" HorizontalAlignment="Left" Margin="138,276,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="button3_Click" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="12,276,0,0" Name="comboBox2" VerticalAlignment="Top" Width="120" />

并添加按钮的后台处理事件:

private void button3_Click(object sender, RoutedEventArgs e)
{
    ks.ElevationAngle = (int)this.comboBox2.SelectedItem;
}

并准备获取角度值并放入下拉列表的方法:

        private void LoadElevationAngle()
        {
            int min = ks.MinElevationAngle;
            int max = ks.MaxElevationAngle;
            for (int i = min; i <= max; i++)
            {
                this.comboBox2.Items.Add(i);
            }
            this.comboBox2.SelectedValue = ks.ElevationAngle;
        }

PS:这里的ks是继续上篇工程中的button2_Click事件中的ks对象提取到了方法外面作为全局变量来访问。并在button2_Click事件中,启动了Kinect后调用LoadElevationAngle()加载kinect角度值。

然后我们就可以通过改变下拉列表中的值后,然后点击按钮,来调整Kinect角度:

然后进入这篇的正题,骨骼信息追踪。

继续在启动前加入代码:

        //添加骨骼数据获取事件
        ks.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(ks_SkeletonFrameReady);
        //设置启动,启动骨骼监听
        ks.SkeletonStream.Enable();

        void ks_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            //获得所有骨骼信息
            SkeletonFrame sf = e.OpenSkeletonFrame();
            if (sf != null)
            {
                //取出骨骼信息
                Skeleton[] arrS = new Skeleton[sf.SkeletonArrayLength];
                sf.CopySkeletonDataTo(arrS);
                Skeleton skeleton = null;
                //获取第一个追踪到的骨骼信息
                foreach (var item in arrS)
                {
                    if (item.TrackingState == SkeletonTrackingState.Tracked)
                    {
                        skeleton = item;
                        break;
                    }
                }
                //如果有,获得这个人的右手点
                if (skeleton != null)
                {
                    Joint hand = skeleton.Joints[JointType.HandRight];
                }
            }
        }

其中JointType包含20个值,可以取人体二十个有效骨骼点信息,但是只有这20个可以用么?理论上不是的,这20个只是kinect提供使用的,更多的点是可以通过算法计算出来位置的。下图介绍了Kinect支持的点的分布情况:

这之后我们能获取好多点的信息,可以应用这些信息能做些什么呢?这个就有待于大家积极地发现了,那么延续上面的功能,再多扩展点功能,使用右手点来控制鼠标移动来玩水果忍着吧,那么在获取到右手点的位置添加下面代码:

                //如果有,获得这个人的右手点
                if (skeleton != null)
                {
                    Joint hand = skeleton.Joints[JointType.HandRight];
                    if (reHand != null)
                    {
                        int x,y;
                        GetScreenPoint(hand, reHand, out x, out y);
                        //鼠标按下
                        mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, 0);
                        //鼠标移动
                        mouse_event(MouseEventFlag.Move, x, y, 0, 0);
                    }
                    reHand = hand;
                }

 

添加方法外的全局变量以及win32函数引用:

        private Joint reHand;
        enum MouseEventFlag : uint
        {
            Move = 0x0001, 
            LeftDown = 0x0002, 
            LeftUp = 0x0004, 
            RightDown = 0x0008, 
            RightUp = 0x0010, 
            MiddleDown = 0x0020, 
            MiddleUp = 0x0040, 
            XDown = 0x0080, 
            XUp = 0x0100, 
            Wheel = 0x0800, 
            VirtualDesk = 0x4000, 
            Absolute = 0x8000
        }

        [DllImport("user32.dll")]
        static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, int extraInfo);

 

补充两个点换算的方法:

        private void GetScreenPoint(Joint hand, Joint hand2, out int w, out int h)
        {
            double w1;
            double h1;
            GetScreenPoint(hand, out w1, out h1);
            double w2;
            double h2;
            GetScreenPoint(hand2, out w2, out h2);
            w = (int)(w1 - w2);
            h = (int)(h1 - h2);
        }

        private void GetScreenPoint(Joint hand, out double w, out double h)
        {
            w = SystemParameters.PrimaryScreenWidth;
            h = SystemParameters.PrimaryScreenHeight;
            w = w / 2 + hand.Position.X * w;
            h = h / 2 - hand.Position.Y * h;
        }

 

 

现在运行起来,并且获得人体信息的时候就会鼠标按下,别且计算两次点的相对坐标来移动鼠标了。怎么样,你的水果忍着能体感了么?呵呵,这篇代码上的比较全了,如果需要帮助,可以留言,或者发送邮件到:57512434@qq.com,看到后会第一时间回复的。

有好多Kinect的应用已经出来了,Kinect控制机器人、代替遥控器、商场试衣,相信陆续会有更多惊喜。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值