找回密码
 立即注册
首页 业界区 业界 Kinect for Windows SDK开发初体验(三)骨骼追踪 ...

Kinect for Windows SDK开发初体验(三)骨骼追踪

百杲憔 2025-5-29 15:49:42
作者:马宁
  我们的Kinect SDK开发开始渐入佳境了,Skeleton Tracking(骨骼追踪)是Kinect的核心技术,正因为有了这项技术,很多有趣的功能才得以实现。
  首先,我们来看一下骨骼追踪的具体实现。Kinect最多可以追踪20个骨骼点,而且目前只能追踪人体,其他的物体或者动物就无能为力了。下图介绍了Kinect骨骼点的分布情况:
  
1.png

  初始化代码

  接下来,我们来看一下骨骼追踪的代码是如何编写的。首先,我们要创建一个新的Visual C#的工程,叫做“SkeletonTracking”,添加Kinect程序集和Coding4Fun程序集的工作,可以参考上一篇“Kinect for Windows SDK开发初体验(二)操作Camera”的内容,在这里不再重复。
  首先我们还是创建Runtime对象,在初始化时,指定UseSkeletalTracking的RuntimeOptions,然后在SkeletonFrameReady事件中添加处理函数。
  1. Runtime nui;
  2. private void Window_Loaded(object sender, RoutedEventArgs e)
  3. {
  4. nui = new Runtime();
  5. nui.Initialize(RuntimeOptions.UseSkeletalTracking);
  6. nui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);
  7. }
复制代码
接下来,窗体关闭时的事件处理函数:
  1. private void Window_Closed(object sender, EventArgs e)
  2. {
  3. nui.Uninitialize();
  4. }
复制代码
如果这个时候,我们在空的nui_SkeletonFrameReady事件处理函数中,添加一个断点:
  1. void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
  2. {
  3. }
复制代码
正确连接Kinect设备,并且站在Kinect前,让Kinect能够正确识别人体时,SkeletonFrameReady事件将被触发。
我们可以通过下图看到返回的事件处理参数,其中比较重要的是SkeletonFrame和Skeletons两个对象。
2.png

添加代码

接下来,我们要准备WPF的界面,在界面上添加五个小球,来跟踪头部、双手和膝盖的位置。在MainPage.xaml中,添加下列代码:
  1. [/code]
  2. 然后,我们在SkeletonFrameReady事件处理函数中添加捕捉SkeletonData的方法:
  3. [code]void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
  4. {
  5. SkeletonFrame allSkeletons = e.SkeletonFrame;
  6. //get the first tracked skeleton
  7. SkeletonData skeleton = (from s in allSkeletons.Skeletons
  8. where s.TrackingState == SkeletonTrackingState.Tracked
  9. select s).FirstOrDefault();
  10. }
复制代码
我们使用了LINQ来获取TrackingState等于Tracked的SkeletonData数据。在SkeletonData对象的Joints属性集合中保存了所有骨骼点的信息。每个骨骼点的信息都是一个Joint对象,其中的Position的X、Y、Z表示了三维位置。其中X和Y的范围都是-1到1,而Z是Kinect到识别物体的距离。
我们可以用下面的代码,将Joint的位置缩放到合适的比例:
  1. Joint j = skeleton.Joints[JointID.HandRight].ScaleTo(640, 480, .5f, .5f);
复制代码
最后两个参数为原始大小的最大值和最小值,上面的语句相当于将-0.5到0.5的范围扩大为0到640的范围。
我们封装了一个函数,将获取到的SkeletonData数据,转换为屏幕上的某一个圆圈:
  1. private void SetEllipsePosition(FrameworkElement ellipse, Joint joint)
  2. {
  3. var scaledJoint = joint.ScaleTo(640, 480, .5f, .5f);
  4. Canvas.SetLeft(ellipse, scaledJoint.Position.X);
  5. Canvas.SetTop(ellipse, scaledJoint.Position.Y);
  6. }
复制代码
最后,我们SkeletonFrameReady事件的处理方法会是这样的:
  1. void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
  2. {
  3. SkeletonFrame allSkeletons = e.SkeletonFrame;
  4. //get the first tracked skeleton
  5. SkeletonData skeleton = (from s in allSkeletons.Skeletons
  6. where s.TrackingState == SkeletonTrackingState.Tracked
  7. select s).FirstOrDefault();
  8. SetEllipsePosition(headEllipse, skeleton.Joints[JointID.Head]);
  9. SetEllipsePosition(leftEllipse, skeleton.Joints[JointID.HandLeft]);
  10. SetEllipsePosition(rightEllipse, skeleton.Joints[JointID.HandRight]);
  11. SetEllipsePosition(KneeLeftEllipse, skeleton.Joints[JointID.KneeLeft]);
  12. SetEllipsePosition(KneeRightEllipse, skeleton.Joints[JointID.KneeRight]);
  13. }
复制代码
最后,程序运行的效果如下,貌似膝盖的识别还是有些问题:
3.png

程序运行时,我们会发现小球运动时会有跳动的问题,为了减少这种情况,我们要设置SkeletonEngine引擎的TransformSmooth属性为true,并指定TransformSmoothParameters参数,根据应用的具体情况,该参数也应该被适当微调。
添加代码后的Load函数,代码如下:
  1. private void Window_Loaded(object sender, RoutedEventArgs e)
  2. {
  3. nui = new Runtime();
  4. nui.Initialize(RuntimeOptions.UseSkeletalTracking);
  5. //Must set to true and set after call to Initialize
  6. nui.SkeletonEngine.TransformSmooth = true;
  7. //Use to transform and reduce jitter
  8. var parameters = new TransformSmoothParameters
  9. {
  10. Smoothing = 0.75f,
  11. Correction = 0.0f,
  12. Prediction = 0.0f,
  13. JitterRadius = 0.05f,
  14. MaxDeviationRadius = 0.04f
  15. };
  16. nui.SkeletonEngine.SmoothParameters = parameters;
  17. nui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);
  18. }
复制代码
写到最后

到这里, Kinect最精华的部分“骨骼追踪”已经介绍给大家了,大家可以去写一些有趣的应用了。接下来,我们会介绍另外一个Kinect的核心功能——Depth Data,景深数据。
 
OpenXLive杯Windows Phone游戏开发大赛

4.jpeg

OpenXLive杯Windows Phone游戏开发大赛,是由OpenXLive联合国内知名的开发者社区:DevDiv、智机网、WPMind、Silverlight银光中国和XNA游戏世界,一起举办的针对Windows Phone游戏开发的比赛。
http://www.openxlive.net/posts/news/40

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册