基本注释都写了,就不废话了
<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