Сравните положение двух суставов с 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 ответ

Проблема в том, что вы используете == в качестве проверки. Вы редко, если вообще когда-либо, столкнетесь с ситуацией, когда два соединения имеют одинаковую ценность. Вы должны использовать >= или же <= для ваших чеков, в зависимости от ваших потребностей.

Например, проверьте JointType.LeftHand >= JointType.RightShoulderи что JointType.LeftHand <= JointType.Spine, для вашей проверки позиции.

Другим решением может быть использование существующей библиотеки жестов для достижения того, чего вы хотите. Вот два из них:

Страница GitHub библиотеки Fizbin объясняет, как настроить и выполнить существующие жесты: Выполнение на жестах. В существующий набор жестов включены жесты "Проведите вправо" и "Проведите пальцем влево", которые выполняются аналогично тому, что вы хотите сделать.

Страницы 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)
  • Пауза: Жест частично завершен (срабатывает, если вы хотите указать, что жест "в движении", но не завершен)
  • Fail: жест не выполняется вообще

Когда у вас есть инициализируемый жест, вам просто нужно отправить "скелетные" данные в библиотеку жестов:

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;
    }
}
Другие вопросы по тегам