我最近开始使用 Microsoft Kinect for Windows SDK 来使用 Kinect 设备编程一些东西。
我正在竭尽全力寻找一种方法来检测某只手是闭合还是张开。
我看到了 Kinect for Windows Toolkit,但文档不存在,我找不到让它工作的方法。
有谁知道检测手部状况的简单方法?如果它不需要使用 Kinect 工具包,那就更好了。
这就是我最终的做法:
首先,我们需要一个看起来像这样的虚拟类:
public class DummyInteractionClient : IInteractionClient
{
public InteractionInfo GetInteractionInfoAtLocation(
int skeletonTrackingId,
InteractionHandType handType,
double x,
double y)
{
var result = new InteractionInfo();
result.IsGripTarget = true;
result.IsPressTarget = true;
result.PressAttractionPointX = 0.5;
result.PressAttractionPointY = 0.5;
result.PressTargetControlId = 1;
return result;
}
}
然后,在主应用程序代码中,我们需要像这样声明交互事件处理程序:
this.interactionStream = new InteractionStream(args.NewSensor, new DummyInteractionClient());
this.interactionStream.InteractionFrameReady += InteractionStreamOnInteractionFrameReady;
最后,处理程序本身的代码:
private void InteractionStreamOnInteractionFrameReady(object sender, InteractionFrameReadyEventArgs e)
{
using (InteractionFrame frame = e.OpenInteractionFrame())
{
if (frame != null)
{
if (this.userInfos == null)
{
this.userInfos = new UserInfo[InteractionFrame.UserInfoArrayLength];
}
frame.CopyInteractionDataTo(this.userInfos);
}
else
{
return;
}
}
foreach (UserInfo userInfo in this.userInfos)
{
foreach (InteractionHandPointer handPointer in userInfo.HandPointers)
{
string action = null;
switch (handPointer.HandEventType)
{
case InteractionHandEventType.Grip:
action = "gripped";
break;
case InteractionHandEventType.GripRelease:
action = "released";
break;
}
if (action != null)
{
string handSide = "unknown";
switch (handPointer.HandType)
{
case InteractionHandType.Left:
handSide = "left";
break;
case InteractionHandType.Right:
handSide = "right";
break;
}
if (handSide == "left")
{
if (action == "released")
{
// left hand released code here
}
else
{
// left hand gripped code here
}
}
else
{
if (action == "released")
{
// right hand released code here
}
else
{
// right hand gripped code here
}
}
}
}
}
}
SDK 1.7 引入了名为“grip”的交互概念。KinectInteraction
您在以下链接中阅读了所有概念:http: //msdn.microsoft.com/en-us/library/dn188673.aspx
微软实现这一点的方式是通过来自KinectRegion
. KinectRegion
事件中有HandPointerGrip
和,它们在HandPointerGripRelease
适当的时刻触发。因为事件来自于手已结束的元素,所以您可以轻松地从事件处理程序中采取适当的行动。
请注意,aKinectRegion
可以是任何东西。基类是一个ContentControl
,因此您可以将像图像这样简单的东西放置Grid
到要操作的区域内的复杂布局中。
您可以在 SDK 提供的ControlBasics-WPF 示例中找到如何使用此交互的示例。
更新:
KinectRegion
只是一个幻想ContentControl
,而它又只是一个容器,里面可以放任何东西。在Kinect for Windows CodePlex中查看ControlBasics-WPF
示例,并在文件中进行搜索。您会看到其中有几个控件可以执行。KinectRegion
MainWindow.xaml
要查看此示例中的实现方式Grip
和GripRelease
实现方式,最好在 Visual Studio 中打开解决方案并搜索“grip”。在我看来,他们这样做的方式有点奇怪,但这是一个流畅的干净实现。
据我所知,Microsoft kinect for windows SDK 不能最好地检测打开和关闭的手。微软提供了 20 个身体部位的跟踪,不包括手指。您可以以不恰当的方式利用 kinect 交互。本教程展示了如何: http ://dotneteers.net/blogs/vbandi/archive/2013/05/03/kinect-interactions-with-wpf-part-iii-demystifying-the-interaction-stream.aspx
但我认为跟踪手指运动的最佳解决方案是使用OpenNI SDK。
OpenNI的一些中间件允许手指跟踪。
你可以使用这样的东西
private void OnHandleHandMove(object source, HandPointerEventArgs args)
{
HandPointer ptr = args.HandPointer;
if (ptr.HandEventType==HandEventType.Grip)
{
// TODO
}
}