用Kinect比较两个关节位置

时间:2013-12-14 17:57:00

标签: c# kinect

我想制作一个Kinect程序,感谢当你的左手X位置越过你的右肩X位置时,它会在PowerPoint上播放以下幻灯片。我已经完成了绘制骨架流的程序部分,并且它正常工作。对于第二部分,我试过这个:

private void NextSlide(Skeleton skeleton)
{
    Joint leftHand = skeleton.Joints[JointType.HandLeft];
    Joint spine = skeleton.Joints[JointType.Spine];
    Joint shoulderRight = skeleton.Joints[JointType.ShoulderRight];
    bool check = false;
    if (leftHand.Position.X == shoulderRight.Position.X && check == false)
    {
        check = true;
        System.Windows.Forms.SendKeys.Send("{RIGHT}");
    }
    if (leftHand.Position.X == spine.Position.X && check == true)
    {
        check = false
    }
}

有谁能解释一下我的代码中的问题是什么? 谢谢,

修改:

我也试过这个:

private void NextSlide(Skeleton skeleton)
{
    Joint leftHand = skeleton.Joints[JointType.HandLeft];
    Joint spine = skeleton.Joints[JointType.Spine];
    Joint shoulderRight = skeleton.Joints[JointType.ShoulderRight];
    double lefthandposition = (int)leftHand.Position.X;
    double shoulderrightposition = (int)shoulderRight.Position.X;
    double spineposition = (int)spine.Position.X;
    bool turn = false;
    double right = lefthandposition - shoulderrightposition;
    bool finish = false;
    double ok = lefthandposition - spineposition;
    if (right < 0)
    {
        turn = true;
    }
    if (ok > 0)
    {
        finish = true;
    }
    bool check = false;
    if (turn == true && check == false && finish == false)
    {
        System.Windows.Forms.SendKeys.Send("{RIGHT}");
        check = true;
        turn = false;
    }
    if (finish == true && check == true && turn == false)
    {
        check = false;
        finish = false;
    }
}

但它也不起作用:/

1 个答案:

答案 0 :(得分:0)

您遇到的问题是您使用==作为检查。如果有的话,你很少会遇到两个关节完全相同的情况。您需要根据自己的需要使用>=<=进行检查。

例如,检查JointType.LeftHand >= JointType.RightShoulderJointType.LeftHand <= JointType.Spine,以进行位置检查。

另一种解决方案可能是使用现有的手势库来完成您想要的任务。以下是其中两个:

Fizbin库的GitHub页面解释了如何设置和执行现有手势:Executing on Gestures。现有手势集中包括“向右滑动”和“向左滑动”手势,其执行类似于您想要执行的操作。

GitHub页面详细介绍,但快速破解将从设置手势库和回调开始:

gestureController = new GestureController();
gestureController.GestureRecognized += OnGestureRecognized;

然后,您将初始化要使用的手势:

IRelativeGestureSegment[] swipeleftSegments = new IRelativeGestureSegment[3];
swipeleftSegments[0] = new SwipeLeftSegment1();
swipeleftSegments[1] = new SwipeLeftSegment2();
swipeleftSegments[2] = new SwipeLeftSegment3();
gestureController.AddGesture("SwipeLeft", swipeleftSegments);

您可以修改现有的手势组件或编写自己的手势组件。几个例子将演示如何比较关节位置。例如,“SwipeLeft”手势中的第一个段落如下:

public class SwipeLeftSegment1 : IRelativeGestureSegment
{
    /// <summary>
    /// Checks the gesture.
    /// </summary>
    /// <param name="skeleton">The skeleton.</param>
    /// <returns>GesturePartResult based on if the gesture part has been completed</returns>
    public GesturePartResult CheckGesture(Skeleton skeleton)
    {

        // right hand in front of right shoulder
        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)
        {
            // right hand below shoulder height but above hip height
            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)
            {
                // right hand right of right shoulder
                if (skeleton.Joints[JointType.HandRight].Position.X > skeleton.Joints[JointType.ShoulderRight].Position.X)
                {
                    return GesturePartResult.Succeed;
                }
                return GesturePartResult.Pausing;
            }
            return GesturePartResult.Fail;
        }
        return GesturePartResult.Fail;
    }
}

请注意,它会经历一系列联合检查并返回以下三种结果之一:

  • 成功:手势已全部完成(当所有'if'语句成功时触发)
  • 暂停:手势部分完成(当您想表明手势处于“动作中”但未完成时触发)
  • 失败:手势根本没有被执行

当你想要初始化手势时,你只需要将'骨架'数据发送到手势库:

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
    using (SkeletonFrame frame = e.OpenSkeletonFrame())
    {
            if (frame == null)
                    return;

            // resize the skeletons array if needed
            if (skeletons.Length != frame.SkeletonArrayLength)
                    skeletons = new Skeleton[frame.SkeletonArrayLength];

            // get the skeleton data
            frame.CopySkeletonDataTo(skeletons);

            foreach (var skeleton in skeletons)
            {
                    // skip the skeleton if it is not being tracked
                    if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
                            continue;

                    // update the gesture controller
                    gestureController.UpdateAllGestures(skeleton);
            }
    }
}

最后,执行手势:

private void OnGestureRecognized(object sender, GestureEventArgs e)
{
    switch (e.GestureName)
    {
            case "SwipeLeft":
                    // do what you want to do
                    break;

            default:
                    break;
    }
}