使用Kinect比较两个关节的位置

本文关键字:两个 位置 Kinect 比较 使用 | 更新日期: 2024-09-24 01:06:10

我想制作一个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;
    }
}

但它也不起作用:/

使用Kinect比较两个关节的位置

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

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

另一种解决方案可能是使用现有的手势库来实现您想要的内容。这里有两个:

  • http://kinecttoolbox.codeplex.com/
  • https://github.com/EvilClosetMonkey/Fizbin.Kinect.Gestures

Fizbin库的GitHub页面解释了如何设置和执行现有手势:在手势上执行。现有手势集中包括"向右滑动"answers"向左滑动"手势,它们的执行方式与您想要做的类似。

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);

您可以修改现有的手势组件,也可以编写自己的组件。以下几个示例将演示如何比较关节位置。例如,"向左滑动"手势中的第一个片段如下:

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;
    }
}