[译]Kinect for Windows SDK开发入门(十八):Kinect Interaction交互控件
本文译自 http://dotneteers.net/blogs/vbandi/archive/2013/03/25/kinect-interactions-with-wpf-part-i-getting-started.aspx,建议直接点击查看。
今年三月份发布了1.7版本的SDK,这一版本的SDK较前一版本最大的变化是添加了Kinect Interactions 和 Kinect Fusion。Kinect Interactions 提供了一些新的带有姿势识别的控件如 push-to-press 按钮, grip-to-pan 列表控件, 而且支持多用户,同时二个人进行的交互,这些新添加的控件能够非常方便的集成到应用程序中,极大的简化了开发和调试过程。

1.7 SDK中新增的第二个功能是去年在Build 2012大会上提到的Kinect Fusion,他能够使我们能快速的创建对象的3D模型,能够用到3D打印,建模,工业设计以及虚拟现实中去。

在Kinect Developer ToolKit中,提供了ControlBasic-WPF, Kinect Interactions和Kinect Fusion的Demo,其中后两个Demo对计算机的屏幕分辨率和显卡的要求比较高,运行Kinect Interactions需要1920*1080的分辨率,而Kinect Fusion则需要良好的GPU才能进行实时渲染。
基于以上原因,本文简要展示Kinect Interactions中提供的新的控件和交互方式。
一 建立必要环境
创建工程之前,您需要到官网上下载最新的1.7 SDK和Developer Toolkit。首先打开Visual Studio创建一个简单的WPF桌面应用程序,然后添加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接口上了等等。
要添加这个控件,首先在主窗体中,添加以下命名空间:
xmlns:k="http://schemas.microsoft.com/kinect/2013"
然后,在主窗体中添加KinectSensorChooserUI控件,代码如下:
<Grid>
<k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" Name="sensorChooserUi" />
</Grid>
在cs代码中,我们需要初始化KinectSensorChooser控件对象:
private KinectSensorChooser sensorChooser;
然后在主窗体的构造函数中注册OnLoad事件:
public MainWindow()
{
InitializeComponent();
Loaded += OnLoaded;
}
创建OnLoaded的委托方法:
private void OnLoaded(object sender, RoutedEventArgs e)
{
this.sensorChooser = new KinectSensorChooser();
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
this.sensorChooser.Start();
}
如果传感器的状态发生改变,比如关闭或者初始化完成,将会触发SensorChooserOnKinectChanged事件。现在为了演示方便,就用MessageBox弹出提示信息:
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
MessageBox.Show(args.NewSensor == null ? "No Kinect" : args.NewSensor.Status.ToString());
}
现在运行系统。如果没有将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 事件代码补全:
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
bool error = false;
if (args.OldSensor != null)
{
try
{
args.OldSensor.DepthStream.Range = DepthRange.Default;
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
args.OldSensor.DepthStream.Disable();
args.OldSensor.SkeletonStream.Disable();
}
catch (InvalidOperationException)
{
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
error = true;
}
}
if (args.NewSensor != null)
{
try
{
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
args.NewSensor.SkeletonStream.Enable();
try
{
args.NewSensor.DepthStream.Range = DepthRange.Near;
args.NewSensor.SkeletonStream.EnableTrackingInNearRange = true;
args.NewSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
}
catch (InvalidOperationException)
{
// Non Kinect for Windows devices do not support Near mode, so reset back to default mode.
args.NewSensor.DepthStream.Range = DepthRange.Default;
args.NewSensor.SkeletonStream.EnableTrackingInNearRange = false;
}
}
catch (InvalidOperationException)
{
error = true;
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
}
}
}
上面的代码可以处理旧的Kinect传感器拔掉,连上新的传感器并开启深度和骨骼数据流的情景,在开发中我们可能会同时连接多个传感器。在try代码中,我们试图开启近景模式,如果用户采用的xbox传感器,则不支持,那么转到一般的模式下。一般情况下,开启近景模式方便调试和用户近距离使用。
二 Kinect交互控件
Kinect Region 控件
要想使用 Kinect Interaction,需要在界面上添加一个KinectRegion容器类。KinectRegion是WPF中使用Kinect Interaction进行交互的关键元素。它是其它Kinect interaction 控件的容器。KinectRegion也负责展示和移动手形图标,即用户的手部骨骼点在界面上的展现。应用程序主界面上可以有多个KinectRegion,但是每个KinectRegion不能够嵌套,每一个KinectRegion中可以有自己的Kinect sensor 对象。
现在,添加一个KinectRegion对象到主窗体上:
<k:KinectRegion Name="kinectRegion"></k:KinectRegion>
然后,设置kinectRegion的KinectSensor属性到我们获取的kinectSensor上:
if (!error)
kinectRegion.KinectSensor = args.NewSensor;
如果运行程序,则会提示错误:

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

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

为了截图和演示,这里有个小技巧,因为要演示,演示的时候必须距离Kinect一定的距离,这样手够不着键盘的PrintScreen键,所以推荐大家使用Kinect Studio 来录制Kinect获取的数据,然后播放该数据来对Kinect应用程序进行调试,这样可以极大提高调试的效率,不必每次都站在Kinect前面进行操作。我先把动作录下来,然后进行截屏或者录屏制作动画,这样方便很多。
KinectUserViewer控件
有时在应用程序中,我们希望能够显示用户自己的影像,以便给予一些反馈,在Kinect.Toolkit.Controls中有KinectUserViewer控件, 可以使用该控件来展示人物的深度影像,要使用它,需要在主界面上定义一个KinectUserViewer对象:
<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到界面上来玩玩。
<k:KinectTileButton Label="Press me!" Click="ButtonOnClick"></k:KinectTileButton>
然后在click事件里面写一些提示:
private void ButtonOnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("You clicked me!");
}
当我们的手没有接触到该控件的时候,他默认为蓝色。当手移动到按钮上时,按钮会变大,并且手形图标周围会出现阴影,以显示当前处于悬浮状态。然后我们将手掌像Kinect方向推,会发现手形图标会根据距离Kinect的距离远近来产生动画,表示我们正在产生“压”按钮的动作。当达到一定的深度阈值时,表示用户已经按下按钮,手形图标会变色,并且会触发Click事件。

KinectCircleButton
KinectCircleButton和KinectTileButton类似,只不过按钮的形状是圆形的,这个可以从名字中可以看出来。要把KinectCircleButton添加到已有的界面布局中,我们需要稍微调整一下。KinectRegion是一个内容控件,表示里面只能有一个子控件,但是,这个子控件可以是一个包含其他容器如Grid或者StackPanel的控件。现在我们需要将之前的KinectTileButton包含到一个Grid控件中,然后将KinectTileButton移到左边,然后在右边添加一个KinectCircleButton控件。
<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中:
<k:KinectScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal" Name="scrollContent" />
</k:KinectScrollViewer>
这个控件就像WPF中的标准ScrollViewer一样。里面有一个StackPanell用来放置滚动的内容,这两个控件组合可以使得内容水平滚动,现在在StackPanel中放置一些KinectCircleButtons.
for (int i = 1; i < 20; i++)
{
var button = new KinectCircleButton
{
Content = i,
Height = 200
};
int i1 = i;
button.Click +=
(o, args) => MessageBox.Show("You clicked button #" + i1);
scrollContent.Children.Add(button);
}
现在运行程序,如下图动画所示,刚开始的时候,可以看到下面的KinectCircleButton;当手移动手到滚动区域,颜色发生变化;然后合上手指,握拳,手势图标会发生变化,表示你当前正在对KinectScrollViewer做抓取操作,移动拳头,KinectScrollViewer控件会把手势图标贴到控件上,就像我们的手指在触摸屏上操作那样,然后里面的button会跟着手势的移动而移动,定位好了之后,放开拳头,就停止移动,这个时候, 对着想要的按钮,将手往前压,就会像前面的控件那样触发Click事件。

说点儿题外话,上面的这个动画录制的有点儿大,有5M多,导致我在Windows Live Write中往博客园中发布的时候,总是提示如下500错误:

谷歌了一下,有的说是图片太大的缘故,于是下载了一个叫Ulead Gif Animator的编辑GIF动画的软件,删掉了一些重复帧,并缩小了尺寸。再次发布就没有这个错误了。
三 结语
本文简要介绍了Kinect for Windows 1.7 SDK中引入的Kinect Interactions功能及相关控件,这些具有Kinect属性的控件极大地简化了我们将Kinect功能添加到应用程序中去的难度,使得我们能够通过Kinect更快更好的创建炫酷的Kinect应用程序。本文的代码点击此处下载,由于大小关系,代码中没有放置KinectInteraction170_32.dll或者KinectInteraction170_64.dll 这两个dll,您自己安装SDK后拷贝到对应目录下运行即可,希望本文对您了解1.7 版 SDK 中的Kinect Interactions 相关控件有所帮助。
[译]Kinect for Windows SDK开发入门(十八):Kinect Interaction交互控件的更多相关文章
- Kinect for Windows SDK开发入门(十九):Kinect Fusion
Kinect for Windows SDK1.7中引入了Kinect Fusion功能.在1.8的SDK中对该功能进行了改进和强化,Kinect Fusion能够使得我们使用Kinect f ...
- Kinect for Windows SDK开发入门(15):进阶指引 下
Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...
- Kinect for Windows SDK开发入门(一):开发环境配置
[译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...
- ]Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/06/KinectSDK_Skeleton_Tracking_Part1.html Kinec ...
- Kinect for Windows SDK开发入门(二):基础知识 上
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/03/31/KinectSDK_Application_Fundamentals_Part1.htm ...
- Kinect for Windows SDK开发入门(四):景深数据处理 上
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/04/KinectSDK_Depth_Image_Processing_Part1.html ...
- Kinect for Windows SDK开发入门(七):骨骼追踪基础 下
http://www.cnblogs.com/yangecnu/archive/2012/04/09/KinectSDK_Skeleton_Tracking_Part2.html 上一篇文章用在UI界 ...
- Kinect for Windows SDK开发入门(三):基础知识 下
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.htm ...
- Kinect for Windows SDK开发学习相关资源
Kinect for Windows SDK(K4W)将Kinect的体感操作带到了平常的应用学习中,提供了一种不同于传统的鼠标,键盘及触摸的无接触的交互方式,在某种程度上实现了自然交互界面的理想,即 ...
随机推荐
- 【leetcode】Remove Duplicates from Sorted List
题目简述 Given a sorted linked list, delete all duplicates such that each element appear only once. For ...
- java中的小数的取整的几种函数
Math类中提供了5个与取整相关的函数,如下所示: static double ceil(double a):天花板函数,返回大于等于a的最小整数(但是以浮点数形式存储). static double ...
- [算法总结]partition (quicksort)
private int partition(int[] nums, int lo, int hi) { if (lo >= hi) { return lo; } int i = lo; int ...
- HTML5开发笔记:图片上传预览
我们知道通过<input type="file">可以用来进行一个图片或者文件的上传,然而浏览器自带的一个缩略图预览的功能其实是相当不美观的,很多时候我们希望可以在上传 ...
- Unity5中WebGL平台封装的一些技巧
最近在接触unity的WebGL平台,其实这个平台作为Web Player的替代品,已经能满足大部分的开发需求,而且不需要额外的插件支持,确实方便了不少,但开发中依旧遇到了不少问题,在这里记录和共享一 ...
- STDIN(0), STDOUT(1), STDERR(2), 2 > &1
当我们在 shell 中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符(文件描述符是一个简单的整数,用以标明每一个被进程所打开的文件和socket.第一个打开的文件是0,第二个是1 ...
- 关于DOM对象与JQuery对象的那些事
这个问题源自上一次的工作室讨论班,主题是"jQuery选择器的使用",在讨论班的结尾,我留了一个思考题: jQuery获取到的对象和直接调用原生Javascript方法获得的对象 ...
- 使用sublime text 开发node.js
http://blog.csdn.net/jwkfreedom/article/details/8450005 本机环境: windows7 64位 1. 下载安装sublime text, 不用注册 ...
- 页面加载完成后,触发事件——trigger()
<button id="btn">点击我</button> <div id="test"></div> 如果页面 ...
- Windows7-USB-DVD-tool提示不能拷贝文件的处理
打开 Windows7-USB-DVD-tool所在目录的log/日志 01/28/2016 02:21:02: Drive selected, H:\; Ready01/28/2016 02:21 ...