├── Fizbin.Kinect.Gestures.v11.suo ├── Fizbin.Kinect.Gestures.Demo ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── App.xaml ├── App.xaml.cs ├── MainWindow.xaml ├── Fizbin.Kinect.Gestures.Demo.csproj └── MainWindow.xaml.cs ├── Fizbin.Kinect.Gestures ├── GestureEnumTypes.cs ├── IRelativeGestureSegment.cs ├── GestureEventArgs.cs ├── Segments │ ├── MenuSegments.cs │ ├── SwipeUp │ │ ├── SwipeUpSegment2.cs │ │ ├── SwipeUpSegment1.cs │ │ └── SwipeUpSegment3.cs │ ├── SwipeDown │ │ ├── SwipeDownSegment2.cs │ │ ├── SwipeDownSegment1.cs │ │ └── SwipeDownSegment3.cs │ ├── WaveLeftSegments.cs │ ├── WaveRightSegments.cs │ ├── JoinedHandsSegment.cs │ ├── ZoomSegments.cs │ ├── SwipeLeftSegments.cs │ └── SwipeRightSegments.cs ├── Properties │ └── AssemblyInfo.cs ├── GestureController.cs ├── Fizbin.Kinect.Gestures.csproj └── Gesture.cs ├── LICENSE.txt ├── .gitignore ├── Fizbin.Kinect.Gestures.sln └── README.md /Fizbin.Kinect.Gestures.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nwpappas/Fizbin.Kinect.Gestures/HEAD/Fizbin.Kinect.Gestures.v11.suo -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace Fizbin.Kinect.Gestures.Demo 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/GestureEnumTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Fizbin.Kinect.Gestures 7 | { 8 | /// 9 | /// the gesture part result 10 | /// 11 | public enum GesturePartResult 12 | { 13 | /// 14 | /// Gesture part fail 15 | /// 16 | Fail, 17 | 18 | /// 19 | /// Gesture part succeed 20 | /// 21 | Succeed, 22 | 23 | /// 24 | /// Gesture part result undetermined 25 | /// 26 | Pausing 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/IRelativeGestureSegment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.Kinect; 6 | 7 | namespace Fizbin.Kinect.Gestures 8 | { 9 | /// 10 | /// Defines a single gesture segment which uses relative positioning 11 | /// of body parts to detect a gesture 12 | /// 13 | public interface IRelativeGestureSegment 14 | { 15 | /// 16 | /// Checks the gesture. 17 | /// 18 | /// The skeleton. 19 | /// GesturePartResult based on if the gesture part has been completed 20 | GesturePartResult CheckGesture(Skeleton skeleton); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/GestureEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fizbin.Kinect.Gestures 4 | { 5 | /// 6 | /// The gesture event arguments 7 | /// 8 | public class GestureEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The gesture type. 14 | /// The tracking ID. 15 | public GestureEventArgs(string name, int trackingId) 16 | { 17 | this.TrackingId = trackingId; 18 | this.GestureName = name; 19 | } 20 | 21 | /// 22 | /// Gets or sets the type of the gesture. 23 | /// 24 | /// 25 | /// The name of the gesture. 26 | /// 27 | public string GestureName { get; set; } 28 | 29 | /// 30 | /// Gets or sets the tracking ID. 31 | /// 32 | /// 33 | /// The tracking ID. 34 | /// 35 | public int TrackingId { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Fizbin.Kinect.Gestures.Demo.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/MenuSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The menu gesture segment 7 | /// 8 | public class MenuSegment1 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // Left and right hands below hip 18 | if (skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.HipCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.HipCenter].Position.Y) 19 | { 20 | // left hand 0.3 to left of center hip 21 | if (skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.HipCenter].Position.X - 0.3) 22 | { 23 | // left hand 0.2 to left of left elbow 24 | if (skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ElbowLeft].Position.X - 0.2) 25 | { 26 | return GesturePartResult.Succeed; 27 | } 28 | } 29 | 30 | return GesturePartResult.Pausing; 31 | } 32 | 33 | return GesturePartResult.Fail; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeUp/SwipeUpSegment2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The second part of the swipe up gesture 7 | /// 8 | public class SwipeUpSegment2 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // right hand in front of right shoulder 18 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ShoulderRight].Position.Z) 19 | { 20 | // right hand above right shoulder 21 | if (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.ShoulderRight].Position.Y) 22 | { 23 | // right hand right of right shoulder 24 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 25 | { 26 | return GesturePartResult.Succeed; 27 | } 28 | return GesturePartResult.Pausing; 29 | } 30 | return GesturePartResult.Fail; 31 | } 32 | return GesturePartResult.Fail; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Fizbin.Kinect.Gestures")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("Fizbin.Kinect.Gestures")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("01011e17-57c6-4a9c-99e0-257e91ef5c30")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeDown/SwipeDownSegment2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The second part of the swipe down gesture for the right hand 7 | /// 8 | public class SwipeDownSegment2 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // right hand in front of right shoulder 18 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 19 | { 20 | // right hand below right elbow 21 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ElbowRight].Position.Y) 22 | { 23 | // right hand right of right shoulder 24 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.HipRight].Position.X) 25 | { 26 | return GesturePartResult.Succeed; 27 | } 28 | return GesturePartResult.Pausing; 29 | } 30 | return GesturePartResult.Fail; 31 | } 32 | return GesturePartResult.Fail; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeUp/SwipeUpSegment1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | using System.Diagnostics; 3 | 4 | namespace Fizbin.Kinect.Gestures.Segments 5 | { 6 | /// 7 | /// The first part of the swipe up gesture 8 | /// 9 | public class SwipeUpSegment1 : IRelativeGestureSegment 10 | { 11 | /// 12 | /// Checks the gesture. 13 | /// 14 | /// The skeleton. 15 | /// GesturePartResult based on if the gesture part has been completed 16 | public GesturePartResult CheckGesture(Skeleton skeleton) 17 | { 18 | 19 | // right hand in front of right elbow 20 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z) 21 | { 22 | // right hand below shoulder height but above hip height 23 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 24 | { 25 | // right hand right of right shoulder 26 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 27 | { 28 | return GesturePartResult.Succeed; 29 | } 30 | return GesturePartResult.Pausing; 31 | } 32 | return GesturePartResult.Fail; 33 | } 34 | return GesturePartResult.Fail; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeUp/SwipeUpSegment3.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The third part of the swipe up gesture 7 | /// 8 | public class SwipeUpSegment3 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // //Right hand in front of right shoulder 18 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ShoulderRight].Position.Z) 19 | { 20 | // right hand above head 21 | if (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.Head].Position.Y) 22 | { 23 | // right hand right of right shoulder 24 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 25 | { 26 | return GesturePartResult.Succeed; 27 | } 28 | return GesturePartResult.Pausing; 29 | } 30 | 31 | // Debug.WriteLine("GesturePart 2 - right hand below shoulder height but above hip height - FAIL"); 32 | return GesturePartResult.Fail; 33 | } 34 | 35 | // Debug.WriteLine("GesturePart 2 - Right hand in front of right Shoulder - FAIL"); 36 | return GesturePartResult.Fail; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeDown/SwipeDownSegment1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | using System.Diagnostics; 3 | 4 | namespace Fizbin.Kinect.Gestures.Segments 5 | { 6 | /// 7 | /// The first part of the swipe down gesture with the right hand 8 | /// 9 | public class SwipeDownSegment1 : IRelativeGestureSegment 10 | { 11 | /// 12 | /// Checks the gesture. 13 | /// 14 | /// The skeleton. 15 | /// GesturePartResult based on if the gesture part has been completed 16 | public GesturePartResult CheckGesture(Skeleton skeleton) 17 | { 18 | 19 | // right hand in front of right shoulder 20 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 21 | { 22 | // right hand below head height and hand higher than elbow 23 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.ElbowRight].Position.Y) 24 | { 25 | // right hand right of right shoulder 26 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 27 | { 28 | return GesturePartResult.Succeed; 29 | } 30 | return GesturePartResult.Pausing; 31 | } 32 | return GesturePartResult.Fail; 33 | } 34 | return GesturePartResult.Fail; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeDown/SwipeDownSegment3.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The third part of the swipe down gesture for the right hand 7 | /// 8 | public class SwipeDownSegment3 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // //Right hand in front of right Shoulder 18 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 19 | { 20 | // right hand below hip 21 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.HipRight].Position.Y) 22 | { 23 | // right hand right of right shoulder 24 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.HipRight].Position.X) 25 | { 26 | return GesturePartResult.Succeed; 27 | } 28 | return GesturePartResult.Pausing; 29 | } 30 | 31 | // Debug.WriteLine("GesturePart 2 - right hand below shoulder height but above hip height - FAIL"); 32 | return GesturePartResult.Fail; 33 | } 34 | 35 | // Debug.WriteLine("GesturePart 2 - Right hand in front of right Shoulder - FAIL"); 36 | return GesturePartResult.Fail; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/GestureController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace Fizbin.Kinect.Gestures 6 | { 7 | public class GestureController 8 | { 9 | /// 10 | /// The list of all gestures we are currently looking for 11 | /// 12 | private List gestures = new List(); 13 | 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | public GestureController() 18 | { 19 | } 20 | 21 | /// 22 | /// Occurs when [gesture recognised]. 23 | /// 24 | public event EventHandler GestureRecognized; 25 | 26 | /// 27 | /// Updates all gestures. 28 | /// 29 | /// The skeleton data. 30 | public void UpdateAllGestures(Skeleton data) 31 | { 32 | foreach (Gesture gesture in this.gestures) 33 | { 34 | gesture.UpdateGesture(data); 35 | } 36 | } 37 | 38 | /// 39 | /// Adds the gesture. 40 | /// 41 | /// The gesture type. 42 | /// The gesture definition. 43 | public void AddGesture(string name, IRelativeGestureSegment[] gestureDefinition) 44 | { 45 | Gesture gesture = new Gesture(name, gestureDefinition); 46 | gesture.GestureRecognized += OnGestureRecognized; 47 | this.gestures.Add(gesture); 48 | } 49 | 50 | /// 51 | /// Handles the GestureRecognized event of the g control. 52 | /// 53 | /// The source of the event. 54 | /// The instance containing the event data. 55 | private void OnGestureRecognized(object sender, GestureEventArgs e) 56 | { 57 | if (this.GestureRecognized != null) 58 | { 59 | this.GestureRecognized(this, e); 60 | } 61 | 62 | foreach (Gesture g in this.gestures) 63 | { 64 | g.Reset(); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/WaveLeftSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | public class WaveLeftSegment1 : IRelativeGestureSegment 6 | { 7 | /// 8 | /// Checks the gesture. 9 | /// 10 | /// The skeleton. 11 | /// GesturePartResult based on if the gesture part has been completed 12 | public GesturePartResult CheckGesture(Skeleton skeleton) 13 | { 14 | // hand above elbow 15 | if (skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.ElbowLeft].Position.Y) 16 | { 17 | // hand right of elbow 18 | if (skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ElbowLeft].Position.X) 19 | { 20 | return GesturePartResult.Succeed; 21 | } 22 | 23 | // hand has not dropped but is not quite where we expect it to be, pausing till next frame 24 | return GesturePartResult.Pausing; 25 | } 26 | 27 | // hand dropped - no gesture fails 28 | return GesturePartResult.Fail; 29 | } 30 | } 31 | 32 | public class WaveLeftSegment2 : IRelativeGestureSegment 33 | { 34 | /// 35 | /// Checks the gesture. 36 | /// 37 | /// The skeleton. 38 | /// GesturePartResult based on if the gesture part has been completed 39 | public GesturePartResult CheckGesture(Skeleton skeleton) 40 | { 41 | // hand above elbow 42 | if (skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.ElbowLeft].Position.Y) 43 | { 44 | // hand right of elbow 45 | if (skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ElbowLeft].Position.X) 46 | { 47 | return GesturePartResult.Succeed; 48 | } 49 | 50 | // hand has not dropped but is not quite where we expect it to be, pausing till next frame 51 | return GesturePartResult.Pausing; 52 | } 53 | 54 | // hand dropped - no gesture fails 55 | return GesturePartResult.Fail; 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/WaveRightSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | public class WaveRightSegment1 : IRelativeGestureSegment 6 | { 7 | /// 8 | /// Checks the gesture. 9 | /// 10 | /// The skeleton. 11 | /// GesturePartResult based on if the gesture part has been completed 12 | public GesturePartResult CheckGesture(Skeleton skeleton) 13 | { 14 | // hand above elbow 15 | if (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.ElbowRight].Position.Y) 16 | { 17 | // hand right of elbow 18 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ElbowRight].Position.X) 19 | { 20 | return GesturePartResult.Succeed; 21 | } 22 | 23 | // hand has not dropped but is not quite where we expect it to be, pausing till next frame 24 | return GesturePartResult.Pausing; 25 | } 26 | 27 | // hand dropped - no gesture fails 28 | return GesturePartResult.Fail; 29 | } 30 | } 31 | 32 | public class WaveRightSegment2 : IRelativeGestureSegment 33 | { 34 | /// 35 | /// Checks the gesture. 36 | /// 37 | /// The skeleton. 38 | /// GesturePartResult based on if the gesture part has been completed 39 | public GesturePartResult CheckGesture(Skeleton skeleton) 40 | { 41 | // hand above elbow 42 | if (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.ElbowRight].Position.Y) 43 | { 44 | // hand right of elbow 45 | if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ElbowRight].Position.X) 46 | { 47 | return GesturePartResult.Succeed; 48 | } 49 | 50 | // hand has not dropped but is not quite where we expect it to be, pausing till next frame 51 | return GesturePartResult.Pausing; 52 | } 53 | 54 | // hand dropped - no gesture fails 55 | return GesturePartResult.Fail; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/JoinedHandsSegment.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | public class JoinedHandsSegment1 : IRelativeGestureSegment 6 | { 7 | /// 8 | /// Checks the gesture. 9 | /// 10 | /// The skeleton. 11 | /// GesturePartResult based on if the gesture part has been completed 12 | public GesturePartResult CheckGesture(Skeleton skeleton) 13 | { 14 | // Right and Left Hand in front of Shoulders 15 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z) 16 | { 17 | // Hands between shoulder and hip 18 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y && 19 | skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 20 | { 21 | // Hands between shoulders 22 | if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X && skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X && 23 | skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X && skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X) 24 | { 25 | // Hands very close 26 | if (skeleton.Joints[JointType.HandRight].Position.X - skeleton.Joints[JointType.HandLeft].Position.X < 0) 27 | { 28 | return GesturePartResult.Succeed; 29 | } 30 | 31 | return GesturePartResult.Pausing; 32 | } 33 | 34 | return GesturePartResult.Fail; 35 | } 36 | 37 | return GesturePartResult.Fail; 38 | } 39 | 40 | return GesturePartResult.Fail; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("Fizbin.Kinect.Gestures.Demo")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Microsoft")] 14 | [assembly: AssemblyProduct("Fizbin.Kinect.Gestures.Demo")] 15 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Microsoft Public License (Ms-PL) 2 | 3 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 4 | 5 | 1. Definitions 6 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the 7 | same meaning here as under U.S. copyright law. 8 | A "contribution" is the original software, or any additions or changes to the software. 9 | A "contributor" is any person that distributes its contribution under this license. 10 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 11 | 12 | 2. Grant of Rights 13 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 14 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 15 | 16 | 3. Conditions and Limitations 17 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 18 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 19 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 20 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 21 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # MSTest test Results 19 | [Tt]est[Rr]esult*/ 20 | [Bb]uild[Ll]og.* 21 | 22 | *_i.c 23 | *_p.c 24 | *.ilk 25 | *.meta 26 | *.obj 27 | *.pch 28 | *.pdb 29 | *.pgc 30 | *.pgd 31 | *.rsp 32 | *.sbr 33 | *.tlb 34 | *.tli 35 | *.tlh 36 | *.tmp 37 | *.tmp_proj 38 | *.log 39 | *.vspscc 40 | *.vssscc 41 | .builds 42 | *.pidb 43 | *.log 44 | *.scc 45 | 46 | # Visual C++ cache files 47 | ipch/ 48 | *.aps 49 | *.ncb 50 | *.opensdf 51 | *.sdf 52 | *.cachefile 53 | 54 | # Visual Studio profiler 55 | *.psess 56 | *.vsp 57 | *.vspx 58 | 59 | # Guidance Automation Toolkit 60 | *.gpState 61 | 62 | # ReSharper is a .NET coding add-in 63 | _ReSharper*/ 64 | *.[Rr]e[Ss]harper 65 | 66 | # TeamCity is a build add-in 67 | _TeamCity* 68 | 69 | # DotCover is a Code Coverage Tool 70 | *.dotCover 71 | 72 | # NCrunch 73 | *.ncrunch* 74 | .*crunch*.local.xml 75 | 76 | # Installshield output folder 77 | [Ee]xpress/ 78 | 79 | # DocProject is a documentation generator add-in 80 | DocProject/buildhelp/ 81 | DocProject/Help/*.HxT 82 | DocProject/Help/*.HxC 83 | DocProject/Help/*.hhc 84 | DocProject/Help/*.hhk 85 | DocProject/Help/*.hhp 86 | DocProject/Help/Html2 87 | DocProject/Help/html 88 | 89 | # Click-Once directory 90 | publish/ 91 | 92 | # Publish Web Output 93 | *.Publish.xml 94 | *.pubxml 95 | 96 | # NuGet Packages Directory 97 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 98 | #packages/ 99 | 100 | # Windows Azure Build Output 101 | csx 102 | *.build.csdef 103 | 104 | # Windows Store app package directory 105 | AppPackages/ 106 | 107 | # Others 108 | sql/ 109 | *.Cache 110 | ClientBin/ 111 | [Ss]tyle[Cc]op.* 112 | ~$* 113 | *~ 114 | *.dbmdl 115 | *.[Pp]ublish.xml 116 | *.pfx 117 | *.publishsettings 118 | 119 | # RIA/Silverlight projects 120 | Generated_Code/ 121 | 122 | # Backup & report files from converting an old project file to a newer 123 | # Visual Studio version. Backup files are not needed, because we have git ;-) 124 | _UpgradeReport_Files/ 125 | Backup*/ 126 | UpgradeLog*.XML 127 | UpgradeLog*.htm 128 | 129 | # SQL Server files 130 | App_Data/*.mdf 131 | App_Data/*.ldf 132 | 133 | # ========================= 134 | # Windows detritus 135 | # ========================= 136 | 137 | # Windows image file caches 138 | Thumbs.db 139 | ehthumbs.db 140 | 141 | # Folder config file 142 | Desktop.ini 143 | 144 | # Recycle Bin used on file shares 145 | $RECYCLE.BIN/ 146 | 147 | # Mac crap 148 | .DS_Store 149 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Fizbin.Kinect.Gestures.Demo.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Fizbin.Kinect.Gestures.Demo.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Fizbin.Kinect.Gestures.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3} 9 | Library 10 | Properties 11 | Fizbin.Kinect.Gestures 12 | Fizbin.Kinect.Gestures 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\..\..\..\..\..\..\Program Files\Microsoft SDKs\Kinect\v1.5\Assemblies\Microsoft.Kinect.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 76 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Gesture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | using System; 3 | 4 | namespace Fizbin.Kinect.Gestures 5 | { 6 | class Gesture 7 | { 8 | /// 9 | /// The parts that make up this gesture 10 | /// 11 | private IRelativeGestureSegment[] gestureParts; 12 | 13 | /// 14 | /// The current gesture part that we are matching against 15 | /// 16 | private int currentGesturePart = 0; 17 | 18 | /// 19 | /// the number of frames to pause for when a pause is initiated 20 | /// 21 | private int pausedFrameCount = 10; 22 | 23 | /// 24 | /// The current frame that we are on 25 | /// 26 | private int frameCount = 0; 27 | 28 | /// 29 | /// Are we paused? 30 | /// 31 | private bool paused = false; 32 | 33 | /// 34 | /// The name of gesture that this is 35 | /// 36 | private string name; 37 | 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | /// The type of gesture. 42 | /// The gesture parts. 43 | public Gesture(string name, IRelativeGestureSegment[] gestureParts) 44 | { 45 | this.gestureParts = gestureParts; 46 | this.name = name; 47 | } 48 | 49 | /// 50 | /// Occurs when [gesture recognised]. 51 | /// 52 | public event EventHandler GestureRecognized; 53 | 54 | /// 55 | /// Updates the gesture. 56 | /// 57 | /// The skeleton data. 58 | public void UpdateGesture(Skeleton data) 59 | { 60 | if (this.paused) 61 | { 62 | if (this.frameCount == this.pausedFrameCount) 63 | { 64 | this.paused = false; 65 | } 66 | 67 | this.frameCount++; 68 | } 69 | 70 | GesturePartResult result = this.gestureParts[this.currentGesturePart].CheckGesture(data); 71 | if (result == GesturePartResult.Succeed) 72 | { 73 | if (this.currentGesturePart + 1 < this.gestureParts.Length) 74 | { 75 | this.currentGesturePart++; 76 | this.frameCount = 0; 77 | this.pausedFrameCount = 10; 78 | this.paused = true; 79 | } 80 | else 81 | { 82 | if (this.GestureRecognized != null) 83 | { 84 | this.GestureRecognized(this, new GestureEventArgs(this.name, data.TrackingId)); 85 | this.Reset(); 86 | } 87 | } 88 | } 89 | else if (result == GesturePartResult.Fail || this.frameCount == 50) 90 | { 91 | this.currentGesturePart = 0; 92 | this.frameCount = 0; 93 | this.pausedFrameCount = 5; 94 | this.paused = true; 95 | } 96 | else 97 | { 98 | this.frameCount++; 99 | this.pausedFrameCount = 5; 100 | this.paused = true; 101 | } 102 | } 103 | 104 | /// 105 | /// Resets this instance. 106 | /// 107 | public void Reset() 108 | { 109 | this.currentGesturePart = 0; 110 | this.frameCount = 0; 111 | this.pausedFrameCount = 5; 112 | this.paused = true; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fizbin.Kinect.Gestures", "Fizbin.Kinect.Gestures\Fizbin.Kinect.Gestures.csproj", "{7471719C-9BD5-42BA-B42B-BB5663EEBBC3}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fizbin.Kinect.Gestures.Demo", "Fizbin.Kinect.Gestures.Demo\Fizbin.Kinect.Gestures.Demo.csproj", "{66669339-32A3-42D4-A83E-744ED4CDE198}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Samples.Kinect.WpfViewers", "..\KinectWpfViewers\Microsoft.Samples.Kinect.WpfViewers.csproj", "{4DE23893-27E7-423F-9BB6-BA21DAC2C45E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Kinect.Toolkit", "..\Microsoft.Kinect.Toolkit\Microsoft.Kinect.Toolkit.csproj", "{C6F9C31B-6130-4443-A5CC-EF0664552ECD}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|Mixed Platforms = Debug|Mixed Platforms 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|Mixed Platforms = Release|Mixed Platforms 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 25 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 26 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 30 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Release|Mixed Platforms.Build.0 = Release|Any CPU 31 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3}.Release|x86.ActiveCfg = Release|Any CPU 32 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Debug|Any CPU.ActiveCfg = Debug|x86 33 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 34 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Debug|Mixed Platforms.Build.0 = Debug|x86 35 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Debug|x86.ActiveCfg = Debug|x86 36 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Debug|x86.Build.0 = Debug|x86 37 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Release|Any CPU.ActiveCfg = Release|x86 38 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Release|Mixed Platforms.ActiveCfg = Release|x86 39 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Release|Mixed Platforms.Build.0 = Release|x86 40 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Release|x86.ActiveCfg = Release|x86 41 | {66669339-32A3-42D4-A83E-744ED4CDE198}.Release|x86.Build.0 = Release|x86 42 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 45 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 46 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Debug|x86.ActiveCfg = Debug|Any CPU 47 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 50 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Release|Mixed Platforms.Build.0 = Release|Any CPU 51 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E}.Release|x86.ActiveCfg = Release|Any CPU 52 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 55 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 56 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Debug|x86.ActiveCfg = Debug|Any CPU 57 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 60 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Release|Mixed Platforms.Build.0 = Release|Any CPU 61 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD}.Release|x86.ActiveCfg = Release|Any CPU 62 | EndGlobalSection 63 | GlobalSection(SolutionProperties) = preSolution 64 | HideSolutionNode = FALSE 65 | EndGlobalSection 66 | EndGlobal 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Except on Tuesdays (Fizbin) Kinect Gesture Library 2 | ================================================== 3 | http://www.exceptontuesdays.com/ 4 | 5 | ##Fizbin.Kinect.Gestures.Demo 6 | Included in the repository is a simple demo application which shows how to easily set up a Kinect enabled application to recognize gestures. 7 | 8 | ###Requirements 9 | The gesture demo takes advantage of helper classes included in the Developer Toolkit, which can be downloaded from the Microsoft Kinect for Windows homepage. 10 | * `Microsoft.Kinect.Toolkit` – Used to reference to `KinectSensorChooser` component, for automatically finding and handling updates to the Kinect sensor. 11 | * `Microsoft.Samples.Kinect.WpfViewers` – Used to reference the `KinectSensorManager` data model class. 12 | 13 | The packages should be placed in the same directory as the Fizbin.Kinect.Gestures solution. 14 | 15 | Both packages can be installed to your computer from the "Developer Toolkit Browser" by installing the "Microsoft.Kinect.Toolkit" and "Kinect Explorer". 16 | 17 | ##Fizbin.Kinect.Gestures 18 | 19 | ###Executing on Gestures 20 | 21 | In order to capture and execute on a gesture we initialize the gesture recognizer’s callback function in `InitializeKinectServices()`: 22 | 23 | ```csharp 24 | gestureController = new GestureController(); 25 | gestureController.GestureRecognized += OnGestureRecognized; 26 | ``` 27 | 28 | After the `GestureController` is initialized you can register new gestures with it. A gesture is made up of one or more `IRelativeGestureSegment`s, which are passed to the `AddGesture` function of the `GestureController` along with a string which can be used for identifying the gesture when the `GestureRecognized` event is fired. 29 | 30 | ```csharp 31 | IRelativeGestureSegment[] swipeleftSegments = new IRelativeGestureSegment[3]; 32 | swipeleftSegments[0] = new SwipeLeftSegment1(); 33 | swipeleftSegments[1] = new SwipeLeftSegment2(); 34 | swipeleftSegments[2] = new SwipeLeftSegment3(); 35 | gestureController.AddGesture("SwipeLeft", swipeleftSegments); 36 | ``` 37 | 38 | The gesture recognizer analyzes data from the skeleton. Each time we receive a new skeleton frame we send it off to the gesture recognizer for review: 39 | 40 | ```csharp 41 | private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) 42 | { 43 | using (SkeletonFrame frame = e.OpenSkeletonFrame()) 44 | { 45 | if (frame == null) 46 | return; 47 | 48 | // resize the skeletons array if needed 49 | if (skeletons.Length != frame.SkeletonArrayLength) 50 | skeletons = new Skeleton[frame.SkeletonArrayLength]; 51 | 52 | // get the skeleton data 53 | frame.CopySkeletonDataTo(skeletons); 54 | 55 | foreach (var skeleton in skeletons) 56 | { 57 | // skip the skeleton if it is not being tracked 58 | if (skeleton.TrackingState != SkeletonTrackingState.Tracked) 59 | continue; 60 | 61 | // update the gesture controller 62 | gestureController.UpdateAllGestures(skeleton); 63 | } 64 | } 65 | } 66 | ``` 67 | 68 | If a gesture is recognized an event will be fired. We go to our event callback and execute on the type of gesture returned: 69 | 70 | ```csharp 71 | private void OnGestureRecognized(object sender, GestureEventArgs e) 72 | { 73 | switch (e.GestureName) 74 | { 75 | case "Menu": 76 | Gesture = "Menu"; 77 | break; 78 | case "WaveRight": 79 | Gesture = "Wave Right"; 80 | break; 81 | case "WaveLeft": 82 | Gesture = "Wave Left"; 83 | break; 84 | case "JoinedHands": 85 | Gesture = "Joined Hands"; 86 | break; 87 | case "SwipeLeft": 88 | Gesture = "Swipe Left"; 89 | break; 90 | case "SwipeRight": 91 | Gesture = "Swipe Right"; 92 | break; 93 | case "ZoomIn": 94 | Gesture = "Zoom In"; 95 | break; 96 | case "ZoomOut": 97 | Gesture = "Zoom Out"; 98 | break; 99 | 100 | default: 101 | break; 102 | } 103 | } 104 | ``` 105 | 106 | That is all that is required. Update any Kinect enabled application with the above lines, in addition to including the gesture library project, and you can execute on basic gestures! 107 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/ZoomSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | public class ZoomSegment1 : IRelativeGestureSegment 6 | { 7 | public GesturePartResult CheckGesture(Skeleton skeleton) 8 | { 9 | // Right and Left Hand in front of Shoulders 10 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z) 11 | { 12 | //Debug.WriteLine("Zoom 0 - Right hand in front of right shoudler - PASS"); 13 | 14 | // Hands between shoulder and hip 15 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y && 16 | skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 17 | { 18 | // Hands between shoulders 19 | if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X && skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X && 20 | skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X && skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X) 21 | { 22 | return GesturePartResult.Succeed; 23 | } 24 | 25 | return GesturePartResult.Pausing; 26 | } 27 | 28 | return GesturePartResult.Fail; 29 | } 30 | 31 | return GesturePartResult.Fail; 32 | } 33 | } 34 | 35 | public class ZoomSegment2 : IRelativeGestureSegment 36 | { 37 | public GesturePartResult CheckGesture(Skeleton skeleton) 38 | { 39 | // Right and Left Hand in front of Shoulders 40 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z) 41 | { 42 | // Hands between shoulder and hip 43 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y && 44 | skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 45 | { 46 | // Hands outside shoulders 47 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X && skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderLeft].Position.X) 48 | { 49 | return GesturePartResult.Succeed; 50 | } 51 | 52 | return GesturePartResult.Pausing; 53 | } 54 | 55 | return GesturePartResult.Fail; 56 | } 57 | 58 | return GesturePartResult.Fail; 59 | } 60 | } 61 | 62 | public class ZoomSegment3 : IRelativeGestureSegment 63 | { 64 | public GesturePartResult CheckGesture(Skeleton skeleton) 65 | { 66 | // Right and Left Hand in front of Shoulders 67 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z) 68 | { 69 | // Hands between shoulder and hip 70 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y && 71 | skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 72 | { 73 | // Hands outside elbows 74 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ElbowRight].Position.X && skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ElbowLeft].Position.X) 75 | { 76 | return GesturePartResult.Succeed; 77 | } 78 | 79 | return GesturePartResult.Pausing; 80 | } 81 | 82 | return GesturePartResult.Fail; 83 | } 84 | 85 | return GesturePartResult.Fail; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeLeftSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The first part of the swipe left gesture 7 | /// 8 | public class SwipeLeftSegment1 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | 18 | // right hand in front of right shoulder 19 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 20 | { 21 | // right hand below shoulder height but above hip height 22 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 23 | { 24 | // right hand right of right shoulder 25 | if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 26 | { 27 | return GesturePartResult.Succeed; 28 | } 29 | return GesturePartResult.Pausing; 30 | } 31 | return GesturePartResult.Fail; 32 | } 33 | return GesturePartResult.Fail; 34 | } 35 | } 36 | 37 | /// 38 | /// The second part of the swipe left gesture 39 | /// 40 | public class SwipeLeftSegment2 : IRelativeGestureSegment 41 | { 42 | /// 43 | /// Checks the gesture. 44 | /// 45 | /// The skeleton. 46 | /// GesturePartResult based on if the gesture part has been completed 47 | public GesturePartResult CheckGesture(Skeleton skeleton) 48 | { 49 | // right hand in front of right shoulder 50 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 51 | { 52 | // right hand below shoulder height but above hip height 53 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 54 | { 55 | // right hand left of right shoulder & right of left shoulder 56 | if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X && skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X) 57 | { 58 | return GesturePartResult.Succeed; 59 | } 60 | return GesturePartResult.Pausing; 61 | } 62 | return GesturePartResult.Fail; 63 | } 64 | return GesturePartResult.Fail; 65 | } 66 | } 67 | 68 | /// 69 | /// The third part of the swipe left gesture 70 | /// 71 | public class SwipeLeftSegment3 : IRelativeGestureSegment 72 | { 73 | /// 74 | /// Checks the gesture. 75 | /// 76 | /// The skeleton. 77 | /// GesturePartResult based on if the gesture part has been completed 78 | public GesturePartResult CheckGesture(Skeleton skeleton) 79 | { 80 | // //Right hand in front of right Shoulder 81 | if (skeleton.Joints[JointType.HandRight].Position.Z < skeleton.Joints[JointType.ElbowRight].Position.Z && skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y) 82 | { 83 | // //right hand below shoulder height but above hip height 84 | if (skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.ShoulderCenter].Position.Y && skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 85 | { 86 | // //right hand left of center hip 87 | if (skeleton.Joints[JointType.HandRight].Position.X < skeleton.Joints[JointType.ShoulderLeft].Position.X) 88 | { 89 | return GesturePartResult.Succeed; 90 | } 91 | 92 | return GesturePartResult.Pausing; 93 | } 94 | 95 | return GesturePartResult.Fail; 96 | } 97 | 98 | return GesturePartResult.Fail; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Fizbin.Kinect.Gestures.Demo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {66669339-32A3-42D4-A83E-744ED4CDE198} 9 | WinExe 10 | Properties 11 | Fizbin.Kinect.Gestures.Demo 12 | Fizbin.Kinect.Gestures.Demo 13 | v4.0 14 | Client 15 | 512 16 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 4 18 | 19 | 20 | x86 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | x86 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | False 41 | ..\..\..\..\..\..\..\Program Files\Microsoft SDKs\Kinect\v1.5\Assemblies\Microsoft.Kinect.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 4.0 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | MSBuild:Compile 64 | Designer 65 | 66 | 67 | App.xaml 68 | Code 69 | 70 | 71 | MainWindow.xaml 72 | Code 73 | 74 | 75 | 76 | 77 | Code 78 | 79 | 80 | True 81 | True 82 | Resources.resx 83 | 84 | 85 | True 86 | Settings.settings 87 | True 88 | 89 | 90 | ResXFileCodeGenerator 91 | Resources.Designer.cs 92 | 93 | 94 | SettingsSingleFileGenerator 95 | Settings.Designer.cs 96 | 97 | 98 | 99 | 100 | 101 | {4DE23893-27E7-423F-9BB6-BA21DAC2C45E} 102 | Microsoft.Samples.Kinect.WpfViewers 103 | 104 | 105 | {C6F9C31B-6130-4443-A5CC-EF0664552ECD} 106 | Microsoft.Kinect.Toolkit 107 | 108 | 109 | {7471719C-9BD5-42BA-B42B-BB5663EEBBC3} 110 | Fizbin.Kinect.Gestures 111 | 112 | 113 | 114 | 121 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures/Segments/SwipeRightSegments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Kinect; 2 | 3 | namespace Fizbin.Kinect.Gestures.Segments 4 | { 5 | /// 6 | /// The first part of the swipe right gesture 7 | /// 8 | public class SwipeRightSegment1 : IRelativeGestureSegment 9 | { 10 | /// 11 | /// Checks the gesture. 12 | /// 13 | /// The skeleton. 14 | /// GesturePartResult based on if the gesture part has been completed 15 | public GesturePartResult CheckGesture(Skeleton skeleton) 16 | { 17 | // //left hand in front of left Shoulder 18 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.HipCenter].Position.Y) 19 | { 20 | // Debug.WriteLine("GesturePart 0 - left hand in front of left Shoulder - PASS"); 21 | // //left hand below shoulder height but above hip height 22 | if (skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 23 | { 24 | // Debug.WriteLine("GesturePart 0 - left hand below shoulder height but above hip height - PASS"); 25 | // //left hand left of left Shoulder 26 | if (skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderLeft].Position.X) 27 | { 28 | // Debug.WriteLine("GesturePart 0 - left hand left of left Shoulder - PASS"); 29 | return GesturePartResult.Succeed; 30 | } 31 | 32 | // Debug.WriteLine("GesturePart 0 - left hand left of left Shoulder - UNDETERMINED"); 33 | return GesturePartResult.Pausing; 34 | } 35 | 36 | // Debug.WriteLine("GesturePart 0 - left hand below shoulder height but above hip height - FAIL"); 37 | return GesturePartResult.Fail; 38 | } 39 | 40 | // Debug.WriteLine("GesturePart 0 - left hand in front of left Shoulder - FAIL"); 41 | return GesturePartResult.Fail; 42 | } 43 | } 44 | 45 | /// 46 | /// The second part of the swipe right gesture 47 | /// 48 | public class SwipeRightSegment2 : IRelativeGestureSegment 49 | { 50 | /// 51 | /// Checks the gesture. 52 | /// 53 | /// The skeleton. 54 | /// GesturePartResult based on if the gesture part has been completed 55 | public GesturePartResult CheckGesture(Skeleton skeleton) 56 | { 57 | // //left hand in front of left Shoulder 58 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.HipCenter].Position.Y) 59 | { 60 | // Debug.WriteLine("GesturePart 1 - left hand in front of left Shoulder - PASS"); 61 | // /left hand below shoulder height but above hip height 62 | if (skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 63 | { 64 | // Debug.WriteLine("GesturePart 1 - left hand below shoulder height but above hip height - PASS"); 65 | // //left hand left of left Shoulder 66 | if (skeleton.Joints[JointType.HandLeft].Position.X < skeleton.Joints[JointType.ShoulderRight].Position.X && skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ShoulderLeft].Position.X) 67 | { 68 | // Debug.WriteLine("GesturePart 1 - left hand left of left Shoulder - PASS"); 69 | return GesturePartResult.Succeed; 70 | } 71 | 72 | // Debug.WriteLine("GesturePart 1 - left hand left of left Shoulder - UNDETERMINED"); 73 | return GesturePartResult.Pausing; 74 | } 75 | 76 | // Debug.WriteLine("GesturePart 1 - left hand below shoulder height but above hip height - FAIL"); 77 | return GesturePartResult.Fail; 78 | } 79 | 80 | // Debug.WriteLine("GesturePart 1 - left hand in front of left Shoulder - FAIL"); 81 | return GesturePartResult.Fail; 82 | } 83 | } 84 | 85 | /// 86 | /// The third part of the swipe right gesture 87 | /// 88 | public class SwipeRightSegment3 : IRelativeGestureSegment 89 | { 90 | /// 91 | /// Checks the gesture. 92 | /// 93 | /// The skeleton. 94 | /// GesturePartResult based on if the gesture part has been completed 95 | public GesturePartResult CheckGesture(Skeleton skeleton) 96 | { 97 | // //left hand in front of left Shoulder 98 | if (skeleton.Joints[JointType.HandLeft].Position.Z < skeleton.Joints[JointType.ElbowLeft].Position.Z && skeleton.Joints[JointType.HandRight].Position.Y < skeleton.Joints[JointType.HipCenter].Position.Y) 99 | { 100 | // //left hand below shoulder height but above hip height 101 | if (skeleton.Joints[JointType.HandLeft].Position.Y < skeleton.Joints[JointType.Head].Position.Y && skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.HipCenter].Position.Y) 102 | { 103 | // //left hand left of left Shoulder 104 | if (skeleton.Joints[JointType.HandLeft].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X) 105 | { 106 | return GesturePartResult.Succeed; 107 | } 108 | 109 | return GesturePartResult.Pausing; 110 | } 111 | 112 | return GesturePartResult.Fail; 113 | } 114 | 115 | return GesturePartResult.Fail; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Fizbin.Kinect.Gestures.Demo/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Data; 3 | using Microsoft.Kinect; 4 | using Microsoft.Kinect.Toolkit; 5 | using Microsoft.Samples.Kinect.WpfViewers; 6 | using System.ComponentModel; 7 | using System; 8 | using System.Timers; 9 | using Fizbin.Kinect.Gestures.Segments; 10 | 11 | namespace Fizbin.Kinect.Gestures.Demo 12 | { 13 | /// 14 | /// Interaction logic for MainWindow.xaml 15 | /// 16 | public partial class MainWindow : Window, INotifyPropertyChanged 17 | { 18 | private readonly KinectSensorChooser sensorChooser = new KinectSensorChooser(); 19 | 20 | private Skeleton[] skeletons = new Skeleton[0]; 21 | 22 | Timer _clearTimer; 23 | 24 | // skeleton gesture recognizer 25 | private GestureController gestureController; 26 | 27 | public MainWindow() 28 | { 29 | DataContext = this; 30 | 31 | InitializeComponent(); 32 | 33 | // initialize the Kinect sensor manager 34 | KinectSensorManager = new KinectSensorManager(); 35 | KinectSensorManager.KinectSensorChanged += this.KinectSensorChanged; 36 | 37 | // locate an available sensor 38 | sensorChooser.Start(); 39 | 40 | // bind chooser's sensor value to the local sensor manager 41 | var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser }; 42 | BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding); 43 | 44 | // add timer for clearing last detected gesture 45 | _clearTimer = new Timer(2000); 46 | _clearTimer.Elapsed += new ElapsedEventHandler(clearTimer_Elapsed); 47 | } 48 | 49 | #region Kinect Discovery & Setup 50 | 51 | private void KinectSensorChanged(object sender, KinectSensorManagerEventArgs args) 52 | { 53 | if (null != args.OldValue) 54 | UninitializeKinectServices(args.OldValue); 55 | 56 | if (null != args.NewValue) 57 | InitializeKinectServices(KinectSensorManager, args.NewValue); 58 | } 59 | 60 | /// 61 | /// Kinect enabled apps should customize which Kinect services it initializes here. 62 | /// 63 | /// 64 | /// 65 | private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor) 66 | { 67 | // Application should enable all streams first. 68 | 69 | // configure the color stream 70 | kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30; 71 | kinectSensorManager.ColorStreamEnabled = true; 72 | 73 | // configure the depth stream 74 | kinectSensorManager.DepthStreamEnabled = true; 75 | 76 | kinectSensorManager.TransformSmoothParameters = 77 | new TransformSmoothParameters 78 | { 79 | Smoothing = 0.5f, 80 | Correction = 0.5f, 81 | Prediction = 0.5f, 82 | JitterRadius = 0.05f, 83 | MaxDeviationRadius = 0.04f 84 | }; 85 | 86 | // configure the skeleton stream 87 | sensor.SkeletonFrameReady += OnSkeletonFrameReady; 88 | kinectSensorManager.SkeletonStreamEnabled = true; 89 | 90 | kinectSensorManager.KinectSensorEnabled = true; 91 | 92 | if (!kinectSensorManager.KinectSensorAppConflict) 93 | { 94 | // initialize the gesture recognizer 95 | gestureController = new GestureController(); 96 | gestureController.GestureRecognized += OnGestureRecognized; 97 | 98 | // register the gestures for this demo 99 | RegisterGestures(); 100 | } 101 | } 102 | 103 | /// 104 | /// Kinect enabled apps should uninitialize all Kinect services that were initialized in InitializeKinectServices() here. 105 | /// 106 | /// 107 | private void UninitializeKinectServices(KinectSensor sensor) 108 | { 109 | // unregister the event handlers 110 | sensor.SkeletonFrameReady -= OnSkeletonFrameReady; 111 | gestureController.GestureRecognized -= OnGestureRecognized; 112 | } 113 | 114 | #endregion Kinect Discovery & Setup 115 | 116 | /// 117 | /// Helper function to register all available 118 | /// 119 | private void RegisterGestures() 120 | { 121 | // define the gestures for the demo 122 | 123 | IRelativeGestureSegment[] joinedhandsSegments = new IRelativeGestureSegment[20]; 124 | JoinedHandsSegment1 joinedhandsSegment = new JoinedHandsSegment1(); 125 | for (int i = 0; i < 20; i++) 126 | { 127 | // gesture consists of the same thing 10 times 128 | joinedhandsSegments[i] = joinedhandsSegment; 129 | } 130 | gestureController.AddGesture("JoinedHands", joinedhandsSegments); 131 | 132 | IRelativeGestureSegment[] menuSegments = new IRelativeGestureSegment[20]; 133 | MenuSegment1 menuSegment = new MenuSegment1(); 134 | for (int i = 0; i < 20; i++) 135 | { 136 | // gesture consists of the same thing 20 times 137 | menuSegments[i] = menuSegment; 138 | } 139 | gestureController.AddGesture("Menu", menuSegments); 140 | 141 | IRelativeGestureSegment[] swipeleftSegments = new IRelativeGestureSegment[3]; 142 | swipeleftSegments[0] = new SwipeLeftSegment1(); 143 | swipeleftSegments[1] = new SwipeLeftSegment2(); 144 | swipeleftSegments[2] = new SwipeLeftSegment3(); 145 | gestureController.AddGesture("SwipeLeft", swipeleftSegments); 146 | 147 | IRelativeGestureSegment[] swiperightSegments = new IRelativeGestureSegment[3]; 148 | swiperightSegments[0] = new SwipeRightSegment1(); 149 | swiperightSegments[1] = new SwipeRightSegment2(); 150 | swiperightSegments[2] = new SwipeRightSegment3(); 151 | gestureController.AddGesture("SwipeRight", swiperightSegments); 152 | 153 | IRelativeGestureSegment[] waveRightSegments = new IRelativeGestureSegment[6]; 154 | WaveRightSegment1 waveRightSegment1 = new WaveRightSegment1(); 155 | WaveRightSegment2 waveRightSegment2 = new WaveRightSegment2(); 156 | waveRightSegments[0] = waveRightSegment1; 157 | waveRightSegments[1] = waveRightSegment2; 158 | waveRightSegments[2] = waveRightSegment1; 159 | waveRightSegments[3] = waveRightSegment2; 160 | waveRightSegments[4] = waveRightSegment1; 161 | waveRightSegments[5] = waveRightSegment2; 162 | gestureController.AddGesture("WaveRight", waveRightSegments); 163 | 164 | IRelativeGestureSegment[] waveLeftSegments = new IRelativeGestureSegment[6]; 165 | WaveLeftSegment1 waveLeftSegment1 = new WaveLeftSegment1(); 166 | WaveLeftSegment2 waveLeftSegment2 = new WaveLeftSegment2(); 167 | waveLeftSegments[0] = waveLeftSegment1; 168 | waveLeftSegments[1] = waveLeftSegment2; 169 | waveLeftSegments[2] = waveLeftSegment1; 170 | waveLeftSegments[3] = waveLeftSegment2; 171 | waveLeftSegments[4] = waveLeftSegment1; 172 | waveLeftSegments[5] = waveLeftSegment2; 173 | gestureController.AddGesture("WaveLeft", waveLeftSegments); 174 | 175 | IRelativeGestureSegment[] zoomInSegments = new IRelativeGestureSegment[3]; 176 | zoomInSegments[0] = new ZoomSegment1(); 177 | zoomInSegments[1] = new ZoomSegment2(); 178 | zoomInSegments[2] = new ZoomSegment3(); 179 | gestureController.AddGesture("ZoomIn", zoomInSegments); 180 | 181 | IRelativeGestureSegment[] zoomOutSegments = new IRelativeGestureSegment[3]; 182 | zoomOutSegments[0] = new ZoomSegment3(); 183 | zoomOutSegments[1] = new ZoomSegment2(); 184 | zoomOutSegments[2] = new ZoomSegment1(); 185 | gestureController.AddGesture("ZoomOut", zoomOutSegments); 186 | 187 | IRelativeGestureSegment[] swipeUpSegments = new IRelativeGestureSegment[3]; 188 | swipeUpSegments[0] = new SwipeUpSegment1(); 189 | swipeUpSegments[1] = new SwipeUpSegment2(); 190 | swipeUpSegments[2] = new SwipeUpSegment3(); 191 | gestureController.AddGesture("SwipeUp", swipeUpSegments); 192 | 193 | IRelativeGestureSegment[] swipeDownSegments = new IRelativeGestureSegment[3]; 194 | swipeDownSegments[0] = new SwipeDownSegment1(); 195 | swipeDownSegments[1] = new SwipeDownSegment2(); 196 | swipeDownSegments[2] = new SwipeDownSegment3(); 197 | gestureController.AddGesture("SwipeDown", swipeDownSegments); 198 | } 199 | 200 | #region Properties 201 | 202 | public static readonly DependencyProperty KinectSensorManagerProperty = 203 | DependencyProperty.Register( 204 | "KinectSensorManager", 205 | typeof(KinectSensorManager), 206 | typeof(MainWindow), 207 | new PropertyMetadata(null)); 208 | 209 | public KinectSensorManager KinectSensorManager 210 | { 211 | get { return (KinectSensorManager)GetValue(KinectSensorManagerProperty); } 212 | set { SetValue(KinectSensorManagerProperty, value); } 213 | } 214 | 215 | /// 216 | /// Gets or sets the last recognized gesture. 217 | /// 218 | private string _gesture; 219 | public String Gesture 220 | { 221 | get { return _gesture; } 222 | 223 | private set 224 | { 225 | if (_gesture == value) 226 | return; 227 | 228 | _gesture = value; 229 | 230 | if (this.PropertyChanged != null) 231 | PropertyChanged(this, new PropertyChangedEventArgs("Gesture")); 232 | } 233 | } 234 | 235 | #endregion Properties 236 | 237 | #region Events 238 | 239 | /// 240 | /// Event implementing INotifyPropertyChanged interface. 241 | /// 242 | public event PropertyChangedEventHandler PropertyChanged; 243 | 244 | #endregion Events 245 | 246 | #region Event Handlers 247 | 248 | /// 249 | /// 250 | /// 251 | /// 252 | /// Gesture event arguments. 253 | private void OnGestureRecognized(object sender, GestureEventArgs e) 254 | { 255 | switch (e.GestureName) 256 | { 257 | case "Menu": 258 | Gesture = "Menu"; 259 | break; 260 | case "WaveRight": 261 | Gesture = "Wave Right"; 262 | break; 263 | case "WaveLeft": 264 | Gesture = "Wave Left"; 265 | break; 266 | case "JoinedHands": 267 | Gesture = "Joined Hands"; 268 | break; 269 | case "SwipeLeft": 270 | Gesture = "Swipe Left"; 271 | break; 272 | case "SwipeRight": 273 | Gesture = "Swipe Right"; 274 | break; 275 | case "SwipeUp": 276 | Gesture = "Swipe Up"; 277 | break; 278 | case "SwipeDown": 279 | Gesture = "Swipe Down"; 280 | break; 281 | case "ZoomIn": 282 | Gesture = "Zoom In"; 283 | break; 284 | case "ZoomOut": 285 | Gesture = "Zoom Out"; 286 | break; 287 | 288 | default: 289 | break; 290 | } 291 | 292 | _clearTimer.Start(); 293 | } 294 | 295 | /// 296 | /// 297 | /// 298 | /// 299 | /// 300 | private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) 301 | { 302 | using (SkeletonFrame frame = e.OpenSkeletonFrame()) 303 | { 304 | if (frame == null) 305 | return; 306 | 307 | // resize the skeletons array if needed 308 | if (skeletons.Length != frame.SkeletonArrayLength) 309 | skeletons = new Skeleton[frame.SkeletonArrayLength]; 310 | 311 | // get the skeleton data 312 | frame.CopySkeletonDataTo(skeletons); 313 | 314 | foreach (var skeleton in skeletons) 315 | { 316 | // skip the skeleton if it is not being tracked 317 | if (skeleton.TrackingState != SkeletonTrackingState.Tracked) 318 | continue; 319 | 320 | // update the gesture controller 321 | gestureController.UpdateAllGestures(skeleton); 322 | } 323 | } 324 | } 325 | 326 | /// 327 | /// Clear text after some time 328 | /// 329 | /// 330 | /// 331 | void clearTimer_Elapsed(object sender, ElapsedEventArgs e) 332 | { 333 | Gesture = ""; 334 | _clearTimer.Stop(); 335 | } 336 | 337 | #endregion Event Handlers 338 | 339 | } 340 | } 341 | --------------------------------------------------------------------------------