我从头开始编写了一个 Kinect 滑动测试程序,该程序读取由 Visual 手势生成器Kinect Swipe Test Project 生成的 gbd 文件。
我想在这个问题中关注的主要 4 个手势是左手和右手向上,左手和右手向上滑动。
在我上面发布的 github 链接中,它可以很好地集成在一起。
但是,当我将代码移植到我的主项目时,左手向上和右手向上滑动手势都出现故障。两种手势都无法检测到。
我不能在这里发布我的主项目,所以我将发布我如何在 2 个主项目文件上实现的代码片段,主要是GestureDetector.cs
和GestureResultsView.cs
以下是我遇到文件问题的相应片段。
手势检测器.cs:
public class GestureDetector : IDisposable
{
//stores an array of paths that leads to the gbd files
private string[] databaseArray = {//Left Hand
@"Database\LeftHandDownToTop.gbd"
//, @"Database\LeftHandHandsUp.gbd"
//, @"Database\LeftHandLeftToRight.gbd"
//, @"Database\LeftHandRightToLeft.gbd"
//Right Hand
, @"Database\RightHandBottomToUp.gbd"
, @"Database\RightHandHandsUp.gbd"
//, @"Database\RightHandLeftToRight.gbd"
//, @"Database\RightHandRightToLeft.gbd"
};
//stores an array of the names of the gesture found inside the gbd file
private string[] databaseGestureNameArray = { //Swipe Up
"SwipeUp_Left",
"SwipeUp_Right",
//Swipe Right
//"SwipeRight_Left",
//"SwipeRight_Right",
//Swipe Left
// "SwipeLeft_Left",
// "SwipeLeft_Right",
//Hands Up
//"HandsUp_Left",
"HandsUp_Right"
};
for (int i = 0; i < databaseArray.Length; i++)
{
// load the 'Seated' gesture from the gesture database
using (VisualGestureBuilderDatabase database = new VisualGestureBuilderDatabase(databaseArray[i]))
{
// 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(databaseGestureNameArray[i]))
{
this.vgbFrameSource.AddGesture(gesture);
}
}
}
}
}
/// <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;
bool foundGesture = false;
if (discreteResults != null)
{
// we only have one gesture in this source object, but you can get multiple gestures
foreach (Gesture gesture in this.vgbFrameSource.Gestures)
{
for (int i = 0; i < databaseGestureNameArray.Length; i++)
{
if (gesture.Name.Equals(databaseGestureNameArray[i]) && gesture.GestureType == GestureType.Discrete)
{
DiscreteGestureResult result = null;
discreteResults.TryGetValue(gesture, out result);
if (result != null && !foundGesture)
{
// update the GestureResultView object with new gesture result values & update the label
foundGesture = this.GestureResultView.UpdateGestureResult(true, result.Detected, result.Confidence, databaseGestureNameArray[i]);
}
}
}
}
}
}
}
}
GestureResultView.cs :
public bool UpdateGestureResult(bool isBodyTrackingIdValid, bool isGestureDetected, float detectionConfidence, string gestureName)
{
this.IsTracked = isBodyTrackingIdValid;
this.Confidence = 0.0f;
bool gestureFound = false;
if (!this.IsTracked)
{
this.ImageSource = this.notTrackedImage;
this.Detected = false;
this.BodyColor = Brushes.Gray;
}
else
{
this.Detected = isGestureDetected;
this.BodyColor = this.trackedColors[this.BodyIndex];
if (this.Detected)
{
this.Confidence = detectionConfidence;
if (this.Confidence > 0.4)
{
this.ImageSource = this.seatedImage;
//https://stackoverflow.com/questions/15425495/change-wpf-mainwindow-label-from-another-class-and-separate-thread
//to change label in other class wpf
//http://the--semicolon.blogspot.co.id/p/change-wpf-window-label-content-from.html
string state = App.Current.Properties["state"].ToString();
switch (gestureName)
{
case "SwipeUp_Right":
SwipeUp(state);
break;
case "SwipeUp_Left":
SwipeUp(state);
break;
case "SwipeDown_Right":
break;
case "SwipeDown_Left":
break;
case "SwipeLeft_Right":
break;
case "SwipeLeft_Left":
break;
case "HandsUp_Right":
if (state.Equals("GoBackHome"))
{
}
else
{
Thread.Sleep(350);
MainWindow.handsUp();
}
break;
case "HandsUp_Left":
if (state.Equals("GoBackHome"))
{
}
else
{
Thread.Sleep(350);
MainWindow.handsUp();
}
break;
}
//"HandsUp_Right"
// , "SwipeRight_Right"
// , "SwipeUp_Right"
// , "SwipeLeft_Right"
// , "HandsUp_Left"
// , "SwipeRight_Left"
gestureFound = true;
}
}
else
{
this.ImageSource = this.notSeatedImage;
}
}
return gestureFound;
}
}
//Routing for gesture start
/// <summary>
/// Take in the current screen, filtered swipe up gesture
/// </summary>
/// <param name="state"></param>
private void SwipeUp(string state)
{
if (state.Equals("Home"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
Home.swipeUp();
}
else if (state.Equals("ItemChoice"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
ItemChoice.swipeUp();
}
else if (state.Equals("ItemParentChoice"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
ItemParentChoice.swipeUp();
}
else if (state.Equals("LoanSummary"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
LoanSummary.swipeUp();
}
else if (state.Equals("Timeslot"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
Timeslot.swipeUp();
}
else if (state.Equals("ViewLoans"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
ViewLoans.swipeUp();
}
else if (state.Equals("WhatToDo"))
{
int milliseconds = 350;
Thread.Sleep(milliseconds);
//await Task.Delay(500);
//WhatToDo.swipeUp();
}
}
/// <summary>
/// Take in the current screen, filtered swipe right gesture
/// </summary>
/// <param name="state"></param>
private void swipeRight(string state)
{
if (state.Equals("Home"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//Home.swipeUp();
}
else if (state.Equals("ItemChoice"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
ItemChoice.swipeRight();
}
else if (state.Equals("ItemParentChoice"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
ItemParentChoice.swipeRight();
}
else if (state.Equals("LoanSummary"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//LoanSummary.swipeUp();
}
else if (state.Equals("Timeslot"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
Timeslot.swipeRight();
}
else if (state.Equals("ViewLoans"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//ViewLoans.swipeUp();
}
else if (state.Equals("WhatToDo"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//Home.swipeUp();
}
}
/// <summary>
/// Take in the current screen, filtered swipe right gesture
/// </summary>
/// <param name="state"></param>
private void swipeLeft(string state)
{
if (state.Equals("Home"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//Home.swipeUp();
}
else if (state.Equals("ItemChoice"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
ItemChoice.swipeLeft();
}
else if (state.Equals("ItemParentChoice"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
ItemParentChoice.swipeLeft();
}
else if (state.Equals("LoanSummary"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//LoanSummary.swipeUp();
}
else if (state.Equals("Timeslot"))
{
int milliseconds = 500;
Thread.Sleep(milliseconds);
Timeslot.swipeLeft();
}
else if (state.Equals("ViewLoans"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//ViewLoans.swipeUp();
}
else if (state.Equals("WhatToDo"))
{
//int milliseconds = 500;
//Thread.Sleep(milliseconds);
//Home.swipeUp();
}
}
//routing for gesture end
}