使用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;
}
}
但它也不起作用:/
遇到的问题是使用==
作为检查。您很少会遇到两个关节的值完全相同的情况。根据您的需要,您需要使用>=
或<=
进行检查。
例如,检查JointType.LeftHand >= JointType.RightShoulder
和JointType.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;
}
}