├── 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 |
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 |
--------------------------------------------------------------------------------