首页 > 代码库 > Kinect 开发 —— WaveHand

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    }}