我正在编写一个基于Kinect的应用程序。我需要实现一个波浪右手势。我使用C#从Internet找到了一个代码片段,但我对这段代码有些怀疑。你能救我吗?
代码:
public class KinectClass
{
public void KinectInitialize ()
{
m_myKinect.Start();
m_myKinect.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
m_myKinect.SkeletonFrameReady += m_myKinect_SkeletonFrameReady;
}
void m_myKinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame frame = e.OpenSkeletonFrame())
{
if (frame != null)
{
if (0 == frame.SkeletonArrayLength) return;
m_skeletons = new Skeleton[frame.SkeletonArrayLength];
if (m_skeletons == null) return;
frame.CopySkeletonDataTo(m_skeletons);
}
}
foreach (Skeleton skeleton in m_skeletons)
{
if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
UpdateSkeletonHistory(skeleton);
value = gestureobject.Detectgesture();
}
}
}
}
此外,还有一个正在检查波函数的Gesture类:
class Gesture
{
private List<Skeleton> SkeletonHistory;
private List<Skeleton> localSkeletonHistory;
public void UpdateSkeletonHistory(Skeleton SkeletonData)
{
SkeletonHistory.Add(SkeletonData);
if (SkeletonHistory.Count > 90)
{
SkeletonHistory.RemoveAt(0);
}
return ;
}
public short Detectgesture()
{
short sReturnvalue = -1;
int gesturePeriod = 2;
int indexesPerSecond = 30;
int indexesToCheck = gesturePeriod * indexesPerSecond;
localSkeletonHistory = new List<Skeleton>(SkeletonHistory);
if (m_SkeletonHistory.Count > indexesToCheck)
{
localSkeletonHistory = new List<Skeleton>(m_SkeletonHistory);
if( waveright() )
{
Console.Writeline("waveright");
}
}
}
private bool waveright()
{
Console.WriteLine("wave right START");
bool Movedright = false,
Movedleft = false;
float refDistance = 0.2F;
float startPos = localSkeletonHistory[0].Joints[JointType.HandLeft].Position.X;
for (int i = 0; i < localSkeletonHistory.Count; i++)
{
if (!(localSkeletonHistory[i].Joints[JointType.HandLeft].Position.Y <= localSkeletonHistory[i].Joints[JointType.Head].Position.Y))
{
break;
}
if (localSkeletonHistory[i].Joints[JointType.HandLeft].Position.X >= (startPos + refDistance))
{
Movedright = true;
}
if (Movedright && Math.Abs(localSkeletonHistory[i].Joints[JointType.HandLeft].Position.X - startPos) <= 0.1 )
{
Movedleft = true;
m_SkeletonHistory.Clear();
break;
}
}
return Movedleft;
}
}
我可以理解Kinect功能,但我对手势功能感到困惑。我的问题如下:
答案 0 :(得分:2)
你需要记住的是,仅仅因为手的位置相对于身体是正确的。这并不意味着他们正在挥手。
右波是向右的过渡。所以你无法确定当前的位置。这就是为什么你需要使用SkeletonHistory跟踪以前的位置。
因此,该算法的简要概述是:
For the previous positions since the last triggered gesture:
If each Skeleton's Y position is greater than the last, then the person is waving right
当然,一只手会向右移动很多次,但这并不意味着它是正确的。所以你需要确定一只手必须向右移动多长时间才能成为一个真正的waveRight手势。
refdistance是一种说法,在将手分类为右波之前,手至少需要移动此距离。
在这里,我相信编码器说这个手势需要持续至少2秒。因此,如果我们每秒获得30个骷髅,那么我们需要检查最后60个骷髅:
int indexesToCheck = gesturePeriod * indexesPerSecond;
msdn文档实际上非常适合这些东西:
https://msdn.microsoft.com/en-us/library/jj131025.aspx
我发现这本书非常适合开始使用这些东西:
Programming with the Kinect for Windows Software Development Kit (Developer Reference)