Kinect SDK 正式版(二)骨骼追踪,实现PC版体感水果忍者
来源:互联网 发布:为什么衍生网络主播 编辑:程序博客网 时间:2024/05/29 16:59
这篇来介绍一下几个正式版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控制机器人、代替遥控器、商场试衣,相信陆续会有更多惊喜。
- Kinect SDK 正式版(二)骨骼追踪,实现PC版体感水果忍者
- Kinect 骨骼追踪数据处理
- kinect骨骼追踪
- Kinect for Windows SDK开发初体验(三)骨骼追踪
- Kinect for Windows SDK开发初体验(三)骨骼追踪
- Kinect for Windows SDK开发初体验(三)骨骼追踪
- PC用Kinect玩水果忍者核心代码
- Kinect开发教程四:用Kinect控制鼠标玩水果忍者PC版
- Kinect开发教程四:用Kinect控制鼠标玩水果忍者PC版
- kinect读取骨骼点数据(二)
- [译]Kinect for Windows SDK开发入门(九):骨骼追踪进阶 下
- Kinect for Windows SDK开发入门(九):骨骼追踪进阶 下
- Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
- Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
- Kinect for Windows SDK开发入门(七):骨骼追踪基础 下
- Kinect for Windows SDK开发入门(八):骨骼追踪进阶 上
- Kinect for Windows SDK开发入门(九):骨骼追踪进阶 下
- [译]Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
- Linux内核地址空间
- 我在使用admob 时遇到的困难和最后解决的办法
- CSS背景(background)的基本用法
- C语言 函数
- SQL 创建数组方法
- Kinect SDK 正式版(二)骨骼追踪,实现PC版体感水果忍者
- 《第三周实验报告任务2》
- linux线程数据及信号量详解
- Service与Activity进行通信
- PL/SQL经验两则
- mysql 行转列
- objectIO 对象序列化Serializable
- Copy On Write(写时复制)
- 使用CreateProcess创建新的process 并返回process运行结束返回值