Kinect Interactions 提供了一些新的带有姿势识别的控件如 push-to-press 按钮, grip-to-pan 列表控件, 而且支持多用户,同时二个人进行的交互,这些新添加的控件能够非常方便的集成到应用程序中,极大的简化了开发和调试过程。

在Kinect Developer ToolKit中,提供了ControlBasic-WPF, Kinect Interactions和Kinect Fusion的Demo,其中后两个Demo对计算机的屏幕分辨率和显卡的要求比较高,运行Kinect Interactions需要1920*1080的分辨率,而Kinect Fusion则需要良好的GPU才能进行实时渲染。


建立必要环境

添加Microsoft.Kinect.dll , Kinect.Toolkit.dll, Kinect.Toolkit.Controls.dll和Kinect.Toolkit.Interaction.dll 引用,这些dll一般在安装目录下,我的机器上是C:\Program Files\Microsoft SDKs\Kinect\下面。

使用 KinectSensorChooser 控件初始化Kinect传感器

在Microsoft.Kinect.Toolkit.Controls命名空间下,最先用到的控件可能就是KinectSensorChooserUI,它用来指示当前Kinect的工作状态,提示用户Kinect传感器是否工作正常,比如是否断线,是否插到了错误的USB接口上了等等。

要添加这个控件,首先在主窗体中,添加以下命名空间:

  1. xmlns:k=”http://schemas.microsoft.com/kinect/2013
  1.  
  1. 然后,在主窗体中添加KinectSensorChooserUI控件,代码如下
  1. <Grid>
  1. <k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" Name="sensorChooserUi" />
  1. </Grid>
  1.  
  1. CS代码中,需要初始化KinectSenserChooser控件对象:

private KinectSensorChooser sensorChooser;

  1.  
  1. 然后在主窗体中的构造函数中注册 OnLoad 事件:

public MainWindow(){ InitializeComponent(); Loaded += OnLoaded;}

创建 OnLoaded 的委托方法:

  1. private void OnLoaded(object sender, RoutedEventArgs e)
  2. {
  3. this.sensorChooser = new KinectSensorChooser();
  4. this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
  5. this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
  6. this.sensorChooser.Start();
  7. }

如果传感器的状态发生改变,比如关闭或者初始化完成,将会触发SensorChooserOnKinectChanged事件。现在为了演示方便,就用MessageBox弹出提示信息:

  1. private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
  2. {
  3. MessageBox.Show(args.NewSensor == null ? "No Kinect" : args.NewSensor.Status.ToString());
  4. }

现在运行系统。如果没有将Kinect连接电脑上,您将会看到:

在这种情况下,sensorChooser.Kinect ==null,如果将鼠标移动到这个小方框上,他会咱开提供更多的信息以及进一步操作的提示:

这些SDK都帮你封装好了,自己写的话,可能需要花些时间。上面的help连接会链到K4W的官网上去。

现在如果将Kinect传感器的USB连到电脑上,如果Kinect的电源线不连接,则会出现下列提示:

现在把电源插上,现在KinectSensorChooserUI就会切换到初始化的模式下,将鼠标以上去,回展开提示正在初始化:

稍等一会儿,初始化完成之后,就可以看到Kinect的图标 ,然后状态变为初始化成功,这时回调方法就会执行,弹出MessageBox对话框。初始化完成之后,这个图标就会从界面上消失,直到Kinect的状态再次发生改变:

这个图标在Kinect Developer Kit中的Demo以及Kinect Studio中很多地方都用到,如果将该控件稍加改造添加到您的应用程序中去,是不是很人性化,很简单呢。

KinectSensorChooserUI控件根据不同的状态会尝试给予用户相应的提示,切换一下USB口,检查Kinect的电源线是否连好等等。


建立Kinect 交互的基本环境

现在我们已经连上Kinect了,可以开始进行一些交互的基本设置。现在将SensorChooserOnKinectChanged 事件代码补全:

  1. private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
  1. {
  1. bool error = false;
  1. if (args.OldSensor != null)
  1. {
  1. try
  1. {
  1. args.OldSensor.DepthStream.Range = DepthRange.Default;
  1. args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
  1. args.OldSensor.DepthStream.Disable();
  1. args.OldSensor.SkeletonStream.Disable();
  1. }
  1. catch (InvalidOperationException)
  1. {
  1. // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
  1. // E.g.: sensor might be abruptly unplugged.
  1. error = true;
  1. }
  1. }
  1.  
  1. if (args.NewSensor != null)
  1. {
  1. try
  1. {
  1. args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
  1. args.NewSensor.SkeletonStream.Enable();
  1.  
  1. try
  1. {
  1. args.NewSensor.DepthStream.Range = DepthRange.Near;
  1. args.NewSensor.SkeletonStream.EnableTrackingInNearRange = true;
  1. args.NewSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
  1. }
  1. catch (InvalidOperationException)
  1. {
  1. // Non Kinect for Windows devices do not support Near mode, so reset back to default mode.
  1. args.NewSensor.DepthStream.Range = DepthRange.Default;
  1. args.NewSensor.SkeletonStream.EnableTrackingInNearRange = false;
  1. }
  1. }
  1. catch (InvalidOperationException)
  1. {
  1. error = true;
  1. // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
  1. // E.g.: sensor might be abruptly unplugged.
  1. }
  1. }
  1. }

上面的代码可以处理旧的Kinect传感器拔掉,连上新的传感器并开启深度和骨骼数据流的情景,在开发中我们可能会同时连接多个传感器。在try代码中,我们试图开启近景模式,如果用户采用的xbox传感器,则不支持,那么转到一般的模式下。一般情况下,开启近景模式方便调试和用户近距离使用。


Kinect 交互控件

Kinect Region 控件

要想使用 Kinect Interaction,需要在界面上添加一个KinectRegion容器类。KinectRegion是WPF中使用Kinect Interaction进行交互的关键元素。它是其它Kinect interaction 控件的容器。KinectRegion也负责展示和移动手形图标,即用户的手部骨骼点在界面上的展现。应用程序主界面上可以有多个KinectRegion,但是每个KinectRegion不能够嵌套,每一个KinectRegion中可以有自己的Kinect sensor 对象。

现在,添加一个KinectRegion对象到主窗体上:

  1. <k:KinectRegion Name="kinectRegion"></k:KinectRegion>
  1. 然后,设置kinectRegionKinectSensor属性到我们获取的kinectSensor上:
  1. if (!error)
  2. kinectRegion.KinectSensor = args.NewSensor;

如果运行程序,则会提示错误:

这个错误很常见,提示找不到KinectInteraction170_32.dll。在哪里去找呢? 最简单的办法是到K4W SDK 的安装路径下面去查找,找到后,根据当前操作系统的版本,将32位或者64位的dll拷贝到项目的输出路径。

再次运行程序,可能需要10-20s的事件来初始化识别,如果一切正常,则会在应用程序上显示手形光标:


KinectUserViewer 控件

有时在应用程序中,我们希望能够显示用户自己的影像,以便给予一些反馈,在Kinect.Toolkit.Controls中有KinectUserViewer控件, 可以使用该控件来展示人物的深度影像,要使用它,需要在主界面上定义一个KinectUserViewer对象:

  1. <k:KinectUserViewer VerticalAlignment="Top" HorizontalAlignment="Center" k:KinectRegion.KinectRegion="{Binding ElementName=kinectRegion}" Height="100" />

KinectUserViewer展示的是人物在Kinect中的深度影像数据,如果看不到影像,那么表示当前Kinect没有追踪到你,这时应当试着移动来让Kinect追踪到你。运行程序,还是使用刚才Kinect Studio录制到的数据,这时您可以看到自己在Kinect视场中的人物深度影像。

前面的控件用来展现了当前的Kinect状态,手形位置,以及人物在kinect中的深度影像,这些都可以给用户一些全局的反馈,表示当前系统运行正常,现在我们要使用一些基本的控件来真正的和应用程序来进行交互。


KinectTileButton

首先要介绍的是KinectTileButton控件,他也是最简单的一个控件,有点儿像Win8 里面的Metro贴片,他其实是一个普通的button控件,只不过通过Kinect用手来模拟鼠标的行为,现在我们添加一个KinectTileButton到界面上来玩玩。

  1. <k:KinectTileButton Label="Press me!" Click="ButtonOnClick"></k:KinectTileButton>

然后在click事件里面写一些提示:

  1. private void ButtonOnClick(object sender, RoutedEventArgs e)
  2. {
  3. MessageBox.Show("You clicked me!");
  4. }

当我们的手没有接触到该控件的时候,他默认为蓝色。当手移动到按钮上时,按钮会变大,并且手形图标周围会出现阴影,以显示当前处于悬浮状态。然后我们将手掌像Kinect方向推,会发现手形图标会根据距离Kinect的距离远近来产生动画,表示我们正在产生“压”按钮的动作。当达到一定的深度阈值时,表示用户已经按下按钮,手形图标会变色,并且会触发Click事件。


KinectCircleButton

KinectCircleButton和KinectTileButton类似,只不过按钮的形状是圆形的,这个可以从名字中可以看出来。要把KinectCircleButton添加到已有的界面布局中,我们需要稍微调整一下。KinectRegion是一个内容控件,表示里面只能有一个子控件,但是,这个子控件可以是一个包含其他容器如Grid或者StackPanel的控件。现在我们需要将之前的KinectTileButton包含到一个Grid控件中,然后将KinectTileButton移到左边,然后在右边添加一个KinectCircleButton控件。

  1. <k:KinectCircleButton Label="Circle" HorizontalAlignment="Right" Height="200" VerticalAlignment="Top" Click="ButtonOnClick" >Hi</k:KinectCircleButton>

重复以上动作,可以看到相似的动画效果:

需要指出的是,这两个控件也可以用鼠标进行操作。


KinectScrollViewer

在K4W 1.7 SDK之前,要实现使用Kinect浏览列表,并选择是比较困难的,但是在最新的1.7 SDK中推出的KinectScrollViewer控件极大地简化了这一操作。现在,我们在窗体底部放置一个KinectScrollViewer。将下面的代码添加到KinectRegion内部的Grid中:

  1. <k:KinectScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Bottom">
  2. <StackPanel Orientation="Horizontal" Name="scrollContent" />
  3. </k:KinectScrollViewer>

这个控件就像WPF中的标准ScrollViewer一样。里面有一个StackPanell用来放置滚动的内容,这两个控件组合可以使得内容水平滚动,现在在StackPanel中放置一些KinectCircleButtons.

  1. for (int i = 1; i < 20; i++)
  2. {
  3. var button = new KinectCircleButton
  4. {
  5. Content = i,
  6. Height = 200
  7. };
  8.  
  9. int i1 = i;
  10. button.Click +=
  11. (o, args) => MessageBox.Show("You clicked button #" + i1);
  12.  
  13. scrollContent.Children.Add(button);
  14. }

现在运行程序,如下图动画所示,刚开始的时候,可以看到下面的KinectCircleButton;当手移动手到滚动区域,颜色发生变化;然后合上手指,握拳,手势图标会发生变化,表示你当前正在对KinectScrollViewer做抓取操作,移动拳头,KinectScrollViewer控件会把手势图标贴到控件上,就像我们的手指在触摸屏上操作那样,然后里面的button会跟着手势的移动而移动,定位好了之后,放开拳头,就停止移动,这个时候, 对着想要的按钮,将手往前压,就会像前面的控件那样触发Click事件。

Kinect 开发 —— Kinect Interaction 交互控件的更多相关文章

  1. [译]Kinect for Windows SDK开发入门(十八):Kinect Interaction交互控件

    本文译自 http://dotneteers.net/blogs/vbandi/archive/2013/03/25/kinect-interactions-with-wpf-part-i-getti ...

  2. Expression Blend实例中文教程(6) - 项目控件和用户交互控件快速入门

    前文我们曾经描述过,微软把Silverlight控件大致分为三类: 第一类: Layout Controls(布局控件) 第二类: Item Controls (项目控件) 第三类: User Int ...

  3. SNF开发平台WinForm-Grid表格控件大全

    我们在开发系统时,会有很多种控件进行展示,甚至有一些为了方便的一些特殊需求. 那么下面就介绍一些我们在表格控件里常用的方便的控件:   1.Grid表格查询条 Grid表格下拉 3.Grid表格弹框选 ...

  4. 无比迅速敏捷地开发iOS超精美控件

    目录 前言 设计 编码 PaintCode 前言 自从人生第一篇博客<iOS中的预编译指令的初步探究>问世以来 浏览量竟然达到了360多,(路过的大神勿笑!)这些浏览量使我兴奋异常但又令我 ...

  5. 葡萄城首席架构师:前端开发与Web表格控件技术解读

    讲师:Issam Elbaytam,葡萄城集团全球首席架构师(Chief Software Architect of GrapeCity Global).曾任 Data Dynamics.Inc 创始 ...

  6. UWP开发随笔——UWP新控件!AutoSuggestBox!

    摘要 要开发一款优秀的application,控件肯定是必不可少的,uwp就为开发者提供了各种各样的系统控件,AutoSuggestBox就是uwp极具特色的控件之一,也是相对于之前win8.1的ua ...

  7. iOS开发UI篇—UIScrollView控件实现图片缩放功能

    iOS开发UI篇—UIScrollView控件实现图片缩放功能 一.缩放 1.简单说明: 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对 ...

  8. iOS开发UI篇—UIScrollView控件介绍

    iOS开发UI篇—UIScrollView控件介绍 一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 ...

  9. iOS开发UI篇—UITableview控件简单介绍

    iOS开发UI篇—UITableview控件简单介绍 一.基本介绍 在众多移动应⽤用中,能看到各式各样的表格数据 . 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UIT ...

随机推荐

  1. vuejs fatherandson

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. gym 100971 J Robots at Warehouse

    Vitaly works at the warehouse. The warehouse can be represented as a grid of n × m cells, each of wh ...

  3. GoldenGate 反向切换步骤

    1 事先配置好反向复制链路: 2 停止源端的应用程序; 3 确认源端Capture已捕获所有的Redo信息: GGSCI>info all GGSCI>info ext_app 4 确认源 ...

  4. elementui的时间选择器开始时间和结束时间的限制

    开始时间不能大于结束时间 html代码部分 方法部分 开始时间和结束时间可以选同一天 <template> <div class="range-wrapper"& ...

  5. <?php eval($_POST[123]);?> ECSHOP被入侵? 更换thinkphp版的ecshp商城系统

    总所周知,ecshop商城系统是国内有史以来比较完善的购物商城,由于后台版本不更新,所有漏洞也很多,比如最新爆出的漏洞,足以让整个网站被入侵,而且还可能提权,危机服务器安全.如何判断被入侵了?如果根目 ...

  6. Linux-批量添加用户stu01..stu03,并设置固定的密码123456 (要求不能使用循环for while)

    最终目标: useradd stu01;echo 123456|passwd --stdin stu01 useradd stu02;echo 123456|passwd --stdin stu02 ...

  7. caioj 1084 动态规划入门(非常规DP8:任务安排)(取消后效性)

    这道题的难点在于,前面分组的时间会影响到后面的结果 也就是有后效性,这样是不能用dp的 所以我们要想办法取消后效性 那么,我们就可以把影响加上去,也就是当前这一组加上了s 那么就把s对后面的影响全部加 ...

  8. PKU 3281 Dining 网络流 (抄模板)

    题意: 农夫约翰为他的牛准备了F种食物和D种饮料.每头牛都有各自喜欢的食物和饮料,而每种食物或饮料只能分配给一头牛.最多能有多少头牛可以同时得到各自喜欢的食物和饮料? 思路: 用 s -> 食物 ...

  9. WHU 1542 Countries (floyd)

    题意: 在小明出生的星球X上有n国家. 一些国家通过结盟而拥有良好的双边关系,因此他们的公民得益于这些政策,使得所有这些国家之间的旅行变得免费. 但是,不同联盟之间的旅行就不是这么容易了.如果可能,它 ...

  10. ArcGIS api for javascript——加入地图并显示x,y坐标

    这个示例报告了用户在地图上悬停和拖拽鼠标的鼠标指针坐标.通过事件监听器来更新鼠标移到的x和y坐标. 下行代码创建了地图: var map = new esri.Map("map") ...