-
Notifications
You must be signed in to change notification settings - Fork 2
/
GestureDetector.cs
351 lines (287 loc) · 15.1 KB
/
GestureDetector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
//------------------------------------------------------------------------------
// <copyright file="GestureDetector.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace Microsoft.Samples.Kinect.DiscreteGestureBasics
{
using System;
using System.Collections.Generic;
using Microsoft.Kinect;
using Microsoft.Kinect.VisualGestureBuilder;
/// <summary>
/// Gesture Detector class which listens for VisualGestureBuilderFrame events from the service
/// and updates the associated GestureResultView object with the latest results for the 'Seated' gesture
/// </summary>
public class GestureDetector : IDisposable
{
/// <summary> Path to the gesture database that was trained with VGB </summary>
private readonly string gestureDatabase = @"Database\Gestures5.gbd";
/// <summary> Name of the discrete gesture in the database that we want to track </summary>
private readonly string SlideRight = "Next_Slide";
private readonly string SlideRightProgress = "Next_SlideProgress";
private readonly string SlideLeft = "Prev_Slide";
private readonly string SlideLeftProgress = "Prev_SlideProgress";
private readonly string close1 = "Close";
private readonly string close1Progress = "CloseProgress";
public static int flag = 0;
/// <summary> Gesture frame source which should be tied to a body tracking ID </summary>
private VisualGestureBuilderFrameSource vgbFrameSource = null;
/// <summary> Gesture frame reader which will handle gesture events coming from the sensor </summary>
private VisualGestureBuilderFrameReader vgbFrameReader = null;
/// <summary>
/// Initializes a new instance of the GestureDetector class along with the gesture frame source and reader
/// </summary>
/// <param name="kinectSensor">Active sensor to initialize the VisualGestureBuilderFrameSource object with</param>
/// <param name="gestureResultView">GestureResultView object to store gesture results of a single body to</param>
public GestureDetector(KinectSensor kinectSensor, GestureResultView gestureResultView)
{
if (kinectSensor == null)
{
throw new ArgumentNullException("kinectSensor");
}
if (gestureResultView == null)
{
throw new ArgumentNullException("gestureResultView");
}
this.GestureResultView = gestureResultView;
// create the vgb source. The associated body tracking ID will be set when a valid body frame arrives from the sensor.
this.vgbFrameSource = new VisualGestureBuilderFrameSource(kinectSensor, 0);
this.vgbFrameSource.TrackingIdLost += this.Source_TrackingIdLost;
// open the reader for the vgb frames
this.vgbFrameReader = this.vgbFrameSource.OpenReader();
if (this.vgbFrameReader != null)
{
this.vgbFrameReader.IsPaused = true;
this.vgbFrameReader.FrameArrived += this.Reader_GestureFrameArrived;
}
// load the 'Seated' gesture from the gesture database
using (VisualGestureBuilderDatabase database = new VisualGestureBuilderDatabase(this.gestureDatabase))
{
// we could load all available gestures in the database with a call to vgbFrameSource.AddGestures(database.AvailableGestures),
// but for this program, we only want to track one discrete gesture from the database, so we'll load it by name
foreach (Gesture gesture in database.AvailableGestures)
{
if (gesture.Name.Equals(this.SlideRight))
{
this.vgbFrameSource.AddGesture(gesture);
}
if (gesture.Name.Equals(this.SlideRightProgress))
{
this.vgbFrameSource.AddGesture(gesture);
}
if (gesture.Name.Equals(this.SlideLeft))
{
this.vgbFrameSource.AddGesture(gesture);
}
if (gesture.Name.Equals(this.SlideLeftProgress))
{
this.vgbFrameSource.AddGesture(gesture);
}
if (gesture.Name.Equals(this.close1))
{
this.vgbFrameSource.AddGesture(gesture);
}
if (gesture.Name.Equals(this.close1Progress))
{
this.vgbFrameSource.AddGesture(gesture);
}
}
}
}
/// <summary> Gets the GestureResultView object which stores the detector results for display in the UI </summary>
public GestureResultView GestureResultView { get; private set; }
/// <summary>
/// Gets or sets the body tracking ID associated with the current detector
/// The tracking ID can change whenever a body comes in/out of scope
/// </summary>
public ulong TrackingId
{
get
{
return this.vgbFrameSource.TrackingId;
}
set
{
if (this.vgbFrameSource.TrackingId != value)
{
this.vgbFrameSource.TrackingId = value;
}
}
}
/// <summary>
/// Gets or sets a value indicating whether or not the detector is currently paused
/// If the body tracking ID associated with the detector is not valid, then the detector should be paused
/// </summary>
public bool IsPaused
{
get
{
return this.vgbFrameReader.IsPaused;
}
set
{
if (this.vgbFrameReader.IsPaused != value)
{
this.vgbFrameReader.IsPaused = value;
}
}
}
/// <summary>
/// Disposes all unmanaged resources for the class
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes the VisualGestureBuilderFrameSource and VisualGestureBuilderFrameReader objects
/// </summary>
/// <param name="disposing">True if Dispose was called directly, false if the GC handles the disposing</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (this.vgbFrameReader != null)
{
this.vgbFrameReader.FrameArrived -= this.Reader_GestureFrameArrived;
this.vgbFrameReader.Dispose();
this.vgbFrameReader = null;
}
if (this.vgbFrameSource != null)
{
this.vgbFrameSource.TrackingIdLost -= this.Source_TrackingIdLost;
this.vgbFrameSource.Dispose();
this.vgbFrameSource = null;
}
}
}
/// <summary>
/// Handles gesture detection results arriving from the sensor for the associated body tracking Id
/// </summary>
/// <param name="sender">object sending the event</param>
/// <param name="e">event arguments</param>
private void Reader_GestureFrameArrived(object sender, VisualGestureBuilderFrameArrivedEventArgs e)
{
VisualGestureBuilderFrameReference frameReference = e.FrameReference;
using (VisualGestureBuilderFrame frame = frameReference.AcquireFrame())
{
if (frame != null)
{
// get the discrete gesture results which arrived with the latest frame
IReadOnlyDictionary<Gesture, DiscreteGestureResult> discreteResults = frame.DiscreteGestureResults;
var continuousResults = frame.ContinuousGestureResults;
if (discreteResults != null)
{
float steerProgress = this.GestureResultView.SteerProgress;
bool detected = false;
float confidence = 0.0f;
bool right = false;
bool left = false;
bool close = false;
foreach (Gesture gesture in this.vgbFrameSource.Gestures)
{
// we only have one gesture in this source object, but you can get multiple gestures
if (gesture.Name.Equals(this.SlideRight) && gesture.GestureType == GestureType.Discrete)
{
DiscreteGestureResult result = null;
discreteResults.TryGetValue(gesture, out result);
if (result != null)
{
detected = result.Detected;
confidence = result.Confidence;
right = true;
left = false;
close = false;
/*this.GestureResultView.UpdateGestureResult(true, detected, confidence, steerProgress, right, left);
break;*/
}
}
if (gesture.Name.Equals(this.SlideLeft) && gesture.GestureType == GestureType.Discrete)
{
DiscreteGestureResult result = null;
discreteResults.TryGetValue(gesture, out result);
if (result != null)
{
detected = result.Detected;
confidence = result.Confidence;
left = true;
right = false;
close = false;
/*this.GestureResultView.UpdateGestureResult(true, detected, confidence, steerProgress, right, left);
break;*/
}
}
if (gesture.Name.Equals(this.close1) && gesture.GestureType == GestureType.Discrete)
{
DiscreteGestureResult result = null;
discreteResults.TryGetValue(gesture, out result);
if (result != null)
{
detected = result.Detected;
confidence = result.Confidence;
right = false;
left = false;
close = true;
}
}
if (continuousResults != null)
{
if (gesture.Name.Equals(this.SlideRightProgress) && gesture.GestureType == GestureType.Continuous)
{
ContinuousGestureResult result = null;
continuousResults.TryGetValue(gesture, out result);
if (result != null)
{
steerProgress = result.Progress;
right = true;
left = false;
close = false;
}
}
if (gesture.Name.Equals(this.close1Progress) && gesture.GestureType == GestureType.Continuous)
{
ContinuousGestureResult result = null;
continuousResults.TryGetValue(gesture, out result);
if (result != null)
{
steerProgress = result.Progress;
right = false;
left = false;
close = true;
}
}
if (gesture.Name.Equals(this.SlideLeftProgress) && gesture.GestureType == GestureType.Continuous)
{
ContinuousGestureResult result = null;
continuousResults.TryGetValue(gesture, out result);
if (result != null)
{
steerProgress = result.Progress;
left = true;
right = false;
close = false;
}
}
}
flag = 1;
this.GestureResultView.UpdateGestureResult(true, detected, confidence, steerProgress, right, left,close);
}
// update the GestureResultView object with new gesture result values
}
}
}
}
/// <summary>
/// Handles the TrackingIdLost event for the VisualGestureBuilderSource object
/// </summary>
/// <param name="sender">object sending the event</param>
/// <param name="e">event arguments</param>
private void Source_TrackingIdLost(object sender, TrackingIdLostEventArgs e)
{
// update the GestureResultView object to show the 'Not Tracked' image in the UI
this.GestureResultView.UpdateGestureResult(false, false, 0.0f,-1.0f,false,false,false);
}
}
}