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