Kinect编程入门指南

随着对这项新技术感兴趣的程序员、学生和粉丝数量的增加,Kinect编程工具和API的开发也日益增多。本文将探讨Kinect.Toolbox和coding4Fun这两个最常用的API的使用。

在开始之前,需要准备以下工具和环境:

  • C#编程语言
  • Visual Studio 2010 开发环境
  • Kinect设备
  • 下载并安装 Kinect SDK

请确保已经下载并安装了Kinect SDK Beta版本。

首先,需要下载Kinect.Toolbox和Coding4Fun这两个API及其代码。请访问它们的官方网站进行下载。

注意:请确保下载的是适用于WinForm的API和代码。

步骤1:开始使用Microsoft Kinect SDK

下载并安装API后,将在Visual Studio中创建一个新的WinForms项目,并添加这些API的DLL文件作为项目引用。

Kinect SDK的DLL文件通常位于以下路径:

C:\Program Files (x86)\Microsoft Research KinectSDK

接下来,在Visual Studio中打开一个新的WinForms项目,并添加以下API的引用:

using Microsoft.Research.Kinect.Nui; using Kinect.Toolbox; using Coding4Fun.Kinect.Winform;

步骤2:检测手部移动事件

在Kinect编程中,手部是最常用的身体部位,因为它是身体最互动的部分。在本节中,将检测右手的移动,并使用API来确定移动的方向,例如从右到左、从下到上等。

首先,在Form1类中初始化一些字段,这些字段将在后续步骤中使用:

private void Form1_Load(object sender, EventArgs e) { try { nui.Initialize(RuntimeOptions.UseSkeletalTracking); } catch (InvalidOperationException) { MessageBox.Show("Runtime initialization failed. Please make sure Kinect device is plugged in."); return; } // 添加事件 nui.SkeletonFrameReady += new EventHandler(nui_SkeletonFrameReady); SwG.OnGestureDetected += On_GestureDetected; }

步骤3:初始化Kinect并链接事件到方法

现在,将在Form1的加载事件中初始化Kinect,并将其事件链接到相应的方法(C#中的委托机制)。

将以下代码添加到Form1的加载事件中:

private void Form1_Load(object sender, EventArgs e) { try { nui.Initialize(RuntimeOptions.UseSkeletalTracking); } catch (InvalidOperationException) { MessageBox.Show("Runtime initialization failed. Please make sure Kinect device is plugged in."); return; } // 添加事件 nui.SkeletonFrameReady += new EventHandler(nui_SkeletonFrameReady); SwG.OnGestureDetected += On_GestureDetected; }

在这段代码的try-catch块中,启动Kinect设备。如果设备出现问题(例如电源关闭或USB线未连接到计算机),将抛出异常。

在第二个代码块中,检测身体。如果Kinect检测到身体,nui_SkeletonFrameReady方法将响应此事件,此事件有一个参数,即检测到的身体,在Kinect SDK中称为SkeletonFrame。

最后,将移动事件链接到将响应此移动的方法。

步骤4:响应事件

为了响应上一步中看到的两个事件,需要使用与这些事件链接的方法。为此,请将这两个方法添加到Form1类中:

方法1:检测身体的右手(检测第一个骨架的一个关节)。

void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { SkeletonFrame allSkeletons = e.SkeletonFrame; // 获取第一个跟踪的骨架 SkeletonData skeleton = (from s in allSkeletons.Skeletons where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault(); // 测试骨架是否存在并被跟踪 if (skeleton != null && skeleton.TrackingState == SkeletonTrackingState.Tracked) { SwG.Add(skeleton.Joints[JointID.HandRight].Position, nui.SkeletonEngine); // 将这些关节缩放到主屏幕的宽度和高度 Joint scaledRight = skeleton.Joints[JointID.HandRight].ScaleTo((int)SystemInformation.PrimaryMonitorSize.Width, (int)SystemInformation.PrimaryMonitorSize.Height, SkeletonMaxX, SkeletonMaxY); } }

在这段代码中,获取Kinect设备检测到的第一个身体(它可以检测到两个身体),然后将右手与移动事件链接,以检测右手的移动:SwG.Add()...等等。

方法2:检测右手的手势。

为此,请将此方法添加到Form1类中,以响应OnGestureDetected事件:

public void On_GestureDetected(string gest) { // 如果手势是向右滑动,则转到下一张图片 if (gest == "SwipeToRight") suivant(); // 如果手势是向左滑动,则转到上一张图片 if (gest == "SwipeToLeft") precedente(); // 例如:是一个方法 }

当Kinect设备检测到跟踪的关节(右手)向左或向右滑动时,将在此方法中触发手势事件,"SwipeToRight"和"SwipeToLeft"是Kinect.Toolbox API中声明的两个字符串,因此在方法是测试右手是从左到右还是从右到左移动,根据这个手部移动做出相应的操作。

技巧1:如果测试这段代码,会发现对手势的响应太快,没有在应用程序和手势之间获得良好的交互性,因此为了解决这个问题,可以像这样修改SkeletonEngine的抖动:

#region TransformSmooth // 必须设置为true,并在调用Initialize之后设置 nui.SkeletonEngine.TransformSmooth = true; // 用于转换和减少抖动 var parameters = new TransformSmoothParameters { Smoothing = 0.75f, Correction = 0.07f, Prediction = 0.08f, JitterRadius = 0.08f, MaxDeviationRadius = 0.07f }; nui.SkeletonEngine.SmoothParameters = parameters; #endregion

技巧2:在Kinect.toolbox中看到只有两种类型的手势SwipeToRight和SwipeToLeft,其他类型的手势可以通过修改源代码在API中实现,在这个技巧中将看到如何添加BackToFront并在代码中使用它,例如在屏幕上选择某个项目。

首先去Kinect.Toolbox的源代码,在SwipeGestureDetector.cs类中修改LookForGesture()方法,通过添加以下代码:

void LookForGesture() { // 从左到右 if (ScanPositions ((P1, P2) => Math.Abs(P2.Y - P1.Y) < 0.20f, (P1, P2) => P2.X - P1.X > -0.01f, (P1, P2) => Math.Abs(P2.X - P1.X) > 0.2f, 250, 2500)) { RaiseGestureDetected("LeftToRight"); return; } // 从右到左 if (ScanPositions ((P1, P2) => Math.Abs(P2.Y - P1.Y) < 0.20f, (P1, P2) => P2.X - P1.X < 0.01f, (P1, P2) => Math.Abs(P2.X - P1.X) > 0.2f, 250, 2500)) { RaiseGestureDetected("RightToLeft"); return; } // 从后到前 if (ScanPositions ((P1, P2) => Math.Abs(P2.Y - P1.Y) < 0.15f, (P1, P2) => P2.Z - P1.Z < 0.01f, (P1, P2) => Math.Abs(P2.Z - P1.Z) > 0.2f, 250, 2500)) { RaiseGestureDetected("BackToFront"); return; } // 从前到后 if (ScanPositions ((P1, P2) => Math.Abs(P2.Y - P1.Y) < 0.15f, (P1, P2) => P2.Z - P1.Z > -0.04f, (P1, P2) => Math.Abs(P2.Z - P1.Z) > 0.4f, 250, 2500)) { RaiseGestureDetected("FrontToBack"); return; } }

修改这个方法后,编译解决方案以获得新的修改过的DLL,这个修改过的DLL可以替换第一个,现在可以在应用程序中检测到从后到前的手势。

public void On_GestureDetected(string gest) { // 如果手势是向右滑动,则转到下一张图片 if (gest == "SwipeToRight") suivant(); // 如果手势是向左滑动,则转到上一张图片 if (gest == "SwipeToLeft") precedente(); // 如果手势是向前滑动 if (gest == "BackToFront") ClickItem(); // 例如:点击显示的项目 }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485