使用微软Kinect进行手势识别操作的一个简单范例(WPF-C#)

微软在2009年6月2日的E3大展上。正式公布的XBOX360体感周边外设。Natal彻底颠覆了游戏的单一操作。使人机互动的理念更加彻底的展现出来。 它是一种3D体感摄影机(开发代号“Project Natal”),同时它导入了即时动态捕捉、影像辨识、麦克风输入、语音辨识、社群互动等功能。微软的Natal不需要使用任何控制器;它是依靠相机捕捉三维空间中玩家的运动。Kinect 的出现不仅带来了一种新的游戏操控体验,由之引发的让机器“读懂人”的交互方式,也正在引领人机交互技术的新一轮变革。

 

微软在今年的6月16日正式发布了Kinect for Windows SDK beta, 让开发人员可以在Windows上开发出和XBOX上一样的互动程序。

 

Kinect for Windows SDK的下载地址:

http://research.microsoft.com/en-us/um/redmond/projects/kinectsdk/download.aspx

Kinect SDK目前只支持Windows 7,分为x86和x64两个版本。开发工具方面还需要.NET Framework 4.0和Visual Studio 2010 (最低Express版本)的支持。

Kinect SDK的视频开发教程:

http://channel9.msdn.com/Series/KinectSDKQuickstarts?sort=recent#tab_sortBy_recent

Kinect SDK的开发指南:

http://research.microsoft.com/en-us/um/redmond/projects/kinectsdk/guides.aspx

Kinect SDK的官方论坛:

http://social.msdn.microsoft.com/Forums/en-US/kinectsdk/threads

硬件设备的需求是:Kinect for Xbox 360 sensor和Xbox 360 Kinect AC Adapter/ Power Supply。

 

本教程给大家示范一个简单的双手在平面操作的范例:

首先请大家下载,并安装Kinect for Windows SDK

 

用Visual Studio 2010 新建一个WPF工程

为了使代码清晰易读,我们先创建一个类库(KinectLib):

首先要添加如下引用:

Microsoft.Research.Kinect.dll (C:\Program Files\Microsoft Research KinectSDK\Microsoft.Research.Kinect.dll)

PresentationFramework

WindowsBase

把类名称改成:KinectSensor 整个类库代码如下:

 

using System.Windows.Controls;
using Microsoft.Research.Kinect.Nui;
using System;
using System.Windows;

namespace KinectLib
{
    //传递正在移动的点的坐标,
    public delegate void receivePoints(int jointID,double x, double y);
    public class KinectSensor : IDisposable
    {
        public event receivePoints _receivepoints;
        Runtime nui;
        const int RED_IDX = 2;
        const int GREEN_IDX = 1;
        const int BLUE_IDX = 0;
        byte[] depthFrame32 = new byte[320 * 240 * 4];
       
        public KinectSensor()
        {
            #region iniKinect
            nui = new Runtime();

            try
            {
                nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseColor);
            }
            catch (InvalidOperationException)
            {
                System.Windows.MessageBox.Show("未检测到摄像头设备!");
                return;
            }
            nui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);
        }
        void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            SkeletonFrame skeletonFrame = e.SkeletonFrame;
            foreach (SkeletonData data in skeletonFrame.Skeletons)
            {
                if (SkeletonTrackingState.Tracked == data.TrackingState)
                {
                    foreach (Joint joint in data.Joints)
                    {
                        Point jointPos = getDisplayPosition(joint);
                        _receivepoints((int)joint.ID,jointPos.X, jointPos.Y);
                    }
                }
            }
        }
        private Point getDisplayPosition(Joint joint)
        {
            float depthX, depthY;
            nui.SkeletonEngine.SkeletonToDepthImage(joint.Position, out depthX, out depthY);
            depthX = Math.Max(0, Math.Min(depthX * 320, 320));  //convert to 320, 240 space
            depthY = Math.Max(0, Math.Min(depthY * 240, 240));  //convert to 320, 240 space
            int colorX, colorY;
            ImageViewArea iv = new ImageViewArea();
            // only ImageResolution.Resolution640x480 is supported at this point
            nui.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(ImageResolution.Resolution640x480, iv, (int)depthX, (int)depthY, (short)0, out colorX, out colorY);

            // map back to skeleton.Width & skeleton.Height
            //116x87
            return new Point((int)(116 * colorX / 640.0), (int)(87 * colorY / 480));
        }
       #endregion
        public void Dispose()
        {
            nui.Uninitialize();
            Environment.Exit(0);
        }
    }
}
   

Kinect 有3个摄像头,其中一个是景深摄像头,我们只读取分析这个摄像头的数据就足够完成手势的捕捉。

有了这个类库,我们可以很方便的在主窗体调用了:

using KinectLib;

public partial class MainWindow : Window
    {
        KinectSensor ks;
        public MainWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ks = new KinectSensor();
            ks._receivepoints += new receivePoints(ks__receivepoints);
        }

        void ks__receivepoints(int jointID, double x, double y)
        {          
            //    HandLeft = 7,//左手         
            //    HandRight = 11,//右手
            double x1 = x * 8.8;//把取得的位置放大8.8倍=1024
            double y1 = y * 8.8;//把取得的位置放大8.8倍=768

            switch (jointID)
            {
                case 7://左手
                    Canvas.SetLeft(this.leftHand, x1);
                    Canvas.SetTop(this.leftHand, y1);
                    break;
                case 11://右手
                    Canvas.SetLeft(this.rightHand, x1);
                    Canvas.SetTop(this.rightHand, y1);
                    break;
            }


        }

        private void MainWin_Unloaded(object sender, RoutedEventArgs e)
        {
            if (ks is IDisposable)//注销Kinect
            {
                ks.Dispose();
            }
        }

 

 

 

本教程完整代码下载

 

下一篇介绍手势识别:http://blog.csdn.net/soft2buy/article/details/6642458

 

 

 

你可能感兴趣的:(windows,object,Microsoft,express,微软)