Kinect 开发 —— WaveHand

基本注释都写了,就不废话了

<Window x:Class="KinectBasicHandTrackingFrameworkTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="MainWindow" Height="600" Width="800" xmlns:my="clr-namespace:KinectBasicHandTrackingFramework;assembly=KinectBasicHandTrackingFramework">
    <Grid Background="#CCFFFF">
        <!--自定义控件-->
        <my:KinectButton Content="Kinect Button" Height="130" Width="130"  HorizontalAlignment="Left" Margin="576,51,0,0" Name="kinectButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave" />
        <my:HoverButton Content="Hover Button" Height="130" Width="130" HorizontalAlignment="Left" Margin="576,227,0,0"  Name="hoverButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave"/>
        <my:MagnetButton Content="Magnet Button" Height="130" Width="130" HorizontalAlignment="Left" Margin="576,395,0,0" Name="magnetButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave" />
        <ListBox Height="306" HorizontalAlignment="Left" Margin="46,51,0,0" Name="listBox1" VerticalAlignment="Top" Width="296" />
    </Grid>
</Window>


namespace KinectBasicHandTrackingFrameworkTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private KinectSensor _kinectDevice;
        private Skeleton[] _FrameSkeletons;
        private WaveGesture _WaveGesture;   // 此应用程序只能识别这一个手势,有待添加

        public MainWindow()
        {
            InitializeComponent();
            this._WaveGesture = new WaveGesture();
            this._WaveGesture.GestureDetected += new EventHandler(_WaveGesture_GestureDetected);    // 绑定事件,可以检测wave动作
            this._kinectDevice = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
            this._kinectDevice.SkeletonFrameReady += KinectDevice_SkeletonFrameReady;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var button = sender as KinectButton;    // 重写点击方法
            button.Background = new SolidColorBrush(Colors.Green);
        }

        private void Button_KinectCursorLeave(object sender, KinectCursorEventArgs e)
        {
            var button = sender as KinectButton;
            button.Background = new SolidColorBrush(Colors.Red);
        }

        private void KinectDevice_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (SkeletonFrame frame = e.OpenSkeletonFrame())
            {
                if (frame != null)
                {
                    this._FrameSkeletons = new Skeleton[_kinectDevice.SkeletonStream.FrameSkeletonArrayLength];
                    frame.CopySkeletonDataTo(this._FrameSkeletons);

                    DateTime startMarker = DateTime.Now;    // 时间戳
                    this._WaveGesture.Update(this._FrameSkeletons, frame.Timestamp);
                }
            }
        }

        private void _WaveGesture_GestureDetected(object sender, EventArgs e)
        {
            listBox1.Items.Add(string.Format("Wave Detected {0}", DateTime.Now.ToLongTimeString()));

        }
    }
}


namespace KinectBasicHandTrackingFrameworkTest
{
    public class WaveGesture
    {
        #region Member Variables
        private const float WAVE_THRESHOLD = 0.1f;
        private const int WAVE_MOVEMENT_TIMEOUT = 5000;
        private const int LEFT_HAND = 0;
        private const int RIGHT_HAND = 1;
        private const int REQUIRED_ITERATIONS = 4;

        private WaveGestureTracker[,] _PlayerWaveTracker = new WaveGestureTracker[6, 2];

        public event EventHandler GestureDetected;  // 表示将处理不包含事件数据的事件的方法
        #endregion Member Variables

        #region Methods
        public void Update(Skeleton[] skeletons, long frameTimestamp)
        {
            if (skeletons != null)
            {
                Skeleton skeleton;

                for (int i = 0; i < skeletons.Length; i++)
                {
                    skeleton = skeletons[i];

                    if (skeleton.TrackingState != SkeletonTrackingState.NotTracked)
                    {
                        TrackWave(skeleton, true, ref this._PlayerWaveTracker[i, LEFT_HAND], frameTimestamp);   // 六个人分别检测左右手是否挥动
                        TrackWave(skeleton, false, ref this._PlayerWaveTracker[i, RIGHT_HAND], frameTimestamp);
                    }
                    else
                    {
                        this._PlayerWaveTracker[i, LEFT_HAND].Reset();
                        this._PlayerWaveTracker[i, RIGHT_HAND].Reset();
                    }
                }
            }
        }

        private void TrackWave(Skeleton skeleton, bool isLeft, ref WaveGestureTracker tracker, long timestamp)
        {
            JointType handJointId = (isLeft) ? JointType.HandLeft : JointType.HandRight;
            JointType elbowJointId = (isLeft) ? JointType.ElbowLeft : JointType.ElbowRight;
            Joint hand = skeleton.Joints[handJointId];
            Joint elbow = skeleton.Joints[elbowJointId];

            if (hand.TrackingState != JointTrackingState.NotTracked && elbow.TrackingState != JointTrackingState.NotTracked)
            {
                if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp)  // 超过规定时间仍未完成
                {
                    tracker.UpdateState(WaveGestureState.Failure, timestamp);
                    System.Diagnostics.Debug.WriteLine("Fail!");
                }
                else if (hand.Position.Y > elbow.Position.Y)
                {
                    //Using the raw values where (0, 0) is the middle of the screen.  From the user‘s perspective, the X-Axis grows more negative left and more positive right.
                    // 右手坐标系,Z轴射出,Y轴向上,X轴向左,坐标系的单位为米
                    if (hand.Position.X <= elbow.Position.X - WAVE_THRESHOLD)
                    {
                        tracker.UpdatePosition(WavePosition.Left, timestamp);
                    }
                    else if (hand.Position.X >= elbow.Position.X + WAVE_THRESHOLD)
                    {
                        tracker.UpdatePosition(WavePosition.Right, timestamp);
                    }
                    else
                    {
                        tracker.UpdatePosition(WavePosition.Neutral, timestamp);
                    }

                    if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS)
                    {
                        tracker.UpdateState(WaveGestureState.Success, timestamp);   // 重置
                        System.Diagnostics.Debug.WriteLine("Success!");

                        if (GestureDetected != null)
                        {
                            GestureDetected(this, new EventArgs());
                        }
                    }
                }
                else
                {
                    if (tracker.State == WaveGestureState.InProgress)
                    {
                        tracker.UpdateState(WaveGestureState.Failure, timestamp);
                        System.Diagnostics.Debug.WriteLine("Fail!");
                    }
                    else
                    {
                        tracker.Reset();
                    }
                }
            }
            else
            {
                    // 关节点未成功跟踪,重置
                tracker.Reset();
            }
        }
        #endregion Methods

        #region Helper Objects
        private enum WavePosition
        {
            None = 0,
            Left = 1,
            Right = 2,
            Neutral = 3
        }

        private enum WaveGestureState
        {
            None = 0,
            Success = 1,
            Failure = 2,
            InProgress = 3
        }

        private struct WaveGestureTracker
        {
            public int IterationCount;
            public WaveGestureState State;
            public long Timestamp;
            public WavePosition StartPosition;
            public WavePosition CurrentPosition;

            public void UpdateState(WaveGestureState state, long timestamp)
            {
                State = state;
                Timestamp = timestamp;
            }

            public void Reset()
            {
                IterationCount = 0;
                State = WaveGestureState.None;
                Timestamp = 0;
                StartPosition = WavePosition.None;
                CurrentPosition = WavePosition.None;
            }

            public void UpdatePosition(WavePosition position, long timestamp)
            {
                if (CurrentPosition != position)
                {
                    if (position == WavePosition.Left || position == WavePosition.Right)
                    {
                        if (State != WaveGestureState.InProgress)
                        {   // 若向左或向右但不是处理状态(None ,Success ,Failure) ,则重置
                            State = WaveGestureState.InProgress;
                            IterationCount = 0;
                            StartPosition = position;
                        }

                        IterationCount++;   // 挥手过程中状态改变,迭代数++
                    }

                    CurrentPosition = position; // 状态重置
                    Timestamp = timestamp;
                }
            }
        }
        #endregion Helper Objects
    }
}

Kinect 开发 —— WaveHand

时间: 2024-11-14 13:24:36

Kinect 开发 —— WaveHand的相关文章

Kinect 开发 &mdash;&mdash; 开发前的准备工作

Kinect SDK v1.5 支持托管语言和非托管语言 Xbox360的游戏是基于Xbox360开发工具包 (XDK)开发的,Xbox 360和Windows是两个完全不同的系统架构.使用Kinect for windows SDK 编译的代码并不能直接部署到Xbox环境中 Kinect 应用程序必须在一个原生操作系统环境下编译,运行 -- 无法在虚拟机上运行 Kinect 开发 —— 开发前的准备工作,布布扣,bubuko.com

Kinect 开发 &mdash;&mdash; 用户交互设计的若干思考

Metro 风格 windows 8 Kinect Hub 手势原型设计 悬停选择     翻页控制 关节点重叠的处理方法 将箭靶设置在画面的边缘,这样玩家持弓的角度与屏幕保持一个大约45度的锐角,这样Kinect可以很精确的检测到拉弓射箭的动作 手势天生具有一定随意性,而且具有一定的文化背景差异性   手与设备的非接触性 虚拟触摸的界面 Kinect 使交互"柔软化"   确认操作保持简单一致 悬停选择 -- 将手停在想要选择的项目方块或按钮上,等待进度圆圈的填充,这个过程会在T时间

【Kinect开发笔记之(一)】初识Kinect

一.Kinect简介 Kinect是微软在2010年6月14日对XBOX360体感周边外设正式发布的名字.它是一种3D体感摄影机(开发代号"Project Natal"),同时它导入了即时动态捕捉.影像辨识.麦克风输入.语音辨识.社群互动等功能. 二.Kinect分类 Kinect for Xbox 360:该版本设计之初就是为了Xbox 360定制的,并未考虑其他的平台.从微软授权角度而言,它无法用于商业开发. Kinect for Windows : 固件上做了升级,支持"

【Kinect开发笔记之(二)】Kinect for windows发展历程

新版本SDK和旧版本的SDK完全兼容,如果您之前安装过旧版本的,可以直接安装新版本的SDK,但是如果您之前的开发版本是Beta版的,则需要卸载之后再安装新版本.在Kinect for Windows SDK 1.0版本中,SDK和示例文件是打包一起安装的.而在之后的版本,为了可以分别升级,微软把这两者分开独立为Kinect for Windows SDK和Kinect for Windows Developer Toolkit这两部分,所以需要分别下载安装, Kinect for Windows

Kinect 开发 &mdash;&mdash; 骨骼数据与彩色影像和深度影像的对齐

在显示彩色影像和深度影像时最好使用WriteableBitmap对象: 要想将骨骼数据影像和深度影像,或者彩色影像叠加到一起,首先要确定深度影像的分辨率和大小,为了方便,这里将深度影像数据和彩色影像数据都采用640x480Fps30的格式,同时将Grid的大小也设置为640*480. 要将骨骼数据和深度影像数据叠加,需要将关节点转换到深度影像所在空间中,可以直接调用MapSkeletonPointToDepthPoint,如果要将骨骼数据叠加到彩色影像上,只需要调用MapSkeletonPoin

Kinect 开发 &mdash;&mdash; 语音识别(下)

使用定向麦克风进行波束追踪 (Beam Tracking for a Directional Microphone) 可以使用这4个麦克风来模拟定向麦克风产生的效果,这个过程称之为波束追踪(beam tracking) 界面上的细长矩形用来指示某一时刻探测到的说话者的语音方向.矩形有一个旋转变换,在垂直轴上左右摆动,以表示声音的不同来源方向. <Rectangle Fill="#1BA78B" HorizontalAlignment="Left" Margin

Kinect 开发 &mdash;&mdash; 姿势识别

姿势和手势通常会混淆,但是他们是两个不同的概念.当一个人摆一个姿势时,他会保持身体的位置和样子一段时间.但是手势包含有动作,例如用户通过手势在触摸屏上,放大图片等操作. 通常,游戏者很容易模仿指定姿势并且比较容易编写算法来识别指定的姿势.例如,如果开发一个用户在天上飞的游戏. 一种控制游戏的方式是,游戏者像鸟一样挥动手臂.挥动的频率越快游戏角色飞的越快,这是一个手势.还有一种方法是,展开双臂,双臂张得越快开,飞的越快.双臂离身体越近,飞的越慢. 身体以及各个关节点的位置定义了一个姿势.更具体的来

Kinect开发资源汇总

Kinect开发资源汇总   转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinect By doctorimage整理 开发Kinect应用本质上和开发其他Windows应用一样,不同的是该SDK支持Kinect感应器的相关功能,比如彩色图像.深度图像.音频.骨骼动画数据等. 本文整理了Kinect应用开发的相关资源,如果你正在进行Kinect开发或打算进行Kinect开发,这将对你有很大

Kinect 开发 &mdash;&mdash; 引言

自然人机交互设计技术 (全息三维投影,手势肢体识别,眼动跟踪 ...) 符合人类心理的交互方式 自然用户界面 -- Natural User Interface 有机用户界面 -- Organic User Interface   第六感设备 -- 手势识别,摄像头,投影,云计算 通过对熟知的技术的组合,产生一种NB 的应用               http://www.pranavmistry.com/ 追影技术 -- 用普通摄像头结合运动跟踪算法,实现体感 微软的 CamBot 技术,G