c# - Kinect手势分析

标签 c# wpf visual-studio-2010 kinect

我正在使用官方 Kinect SDK 做一个 kinect 应用程序。

我想要的结果
1)能够识别 body 已经挥手5秒。做某事
2) 能够识别单腿倾斜 5 秒。如果确实如此,请做某事。

有谁知道怎么做?我正在做一个 WPF 应用程序。

想举个例子。我对 Kinect 比较陌生。

在此先感谢您的帮助!

最佳答案

Kinect 为您提供它正在跟踪的骨架,剩下的由您来完成。基本上,您需要为您想要的每个手势创建一个定义,并在每次触发 SkeletonFrameReady 事件时针对骨架运行该定义。这并不容易。

定义手势

定义手势可能非常困难。最简单(最简单)的手势是在单个时间点发生的手势,因此不依赖于四肢过去的位置。例如,如果您想检测用户何时将手举过头顶,则可以在每个单独的帧上进行检查。更复杂的手势需要考虑一段时间。对于您的挥手手势,您将无法从单个画面中判断一个人是在挥手还是只是将手举在他们面前。

所以现在您需要能够存储过去的相关信息,但哪些信息是相关的?您是否应该保留最后 30 帧的存储并针对它运行算法? 30 帧只能为您提供一秒钟的信息。也许 60 帧?或者你的 5 秒,300 帧?人类的移动速度没有那么快,所以也许您可以每 5 帧使用一次,这会将您的 5 秒减少到 60 帧。更好的主意是从帧中挑选相关信息。对于挥手手势,手的当前速度、移动了多长时间、移动了多远等都可能是有用的信息。

在您弄清楚如何获取和存储与您的手势有关的所有信息后,您如何将这些数字转化为定义?挥手可能需要特定的最小速度、方向(左/右而不是上/下)或持续时间。但是,此持续时间不是您感兴趣的 5 秒持续时间。此持续时间是假设用户挥手所需的绝对最小值。如上所述,您无法从一帧中确定波浪。你不应该根据 2、3 或 5 来确定波浪,因为时间不够。如果我的手抽动了几分之一秒,你会认为这是一个波浪吗?可能有一个甜蜜点,大多数人会同意从左到右的运动构成一个波,但我当然不太了解它,无法在算法中定义它。

要求用户在一段时间内做某个手势还有另一个问题。有可能,无论您如何编写定义,这五秒钟内的每一帧都不会看起来像波浪。您可以轻松确定某人是否将手举过头顶五秒钟(因为它可以在单个帧的基础上确定),但对于复杂的手势要做到这一点要困难得多。虽然挥手没有那么复杂,但它仍然显示了这个问题。当您的手在波浪的任一侧改变方向时,它会停止移动几分之一秒。那你还在挥手吗?如果你的回答是肯定的,那就更慢地挥手,这样你就可以在两边多暂停一下。那个停顿还会被认为是波浪吗?很有可能,在五秒手势的某个时刻,定义将无法检测到波浪。所以现在你需要考虑手势持续时间的宽大。如果挥手手势发生了最后五秒的 95%,这是否足够好? 90%? 80%?

我想在这里说明的一点是没有简单的方法来进行手势识别。您必须仔细考虑手势并确定某种定义,将一堆关节位置(骨架数据)转换为手势。您需要跟踪过去帧的相关数据,但要意识到手势定义可能并不完美。

考虑用户

因此,既然我已经说明了为什么难以检测到 5 秒波,那么请至少让我谈谈如何做到这一点:不要。您不应该强制用户在设定的时间段(五秒波)内重复基于 Action 的手势。这是令人惊讶的累人,而不是人们对计算机的期望/想要的。指向和点击是瞬间的;一旦我们点击,我们就会期待回应。没有人希望在打开扫雷器之前必须按住鼠标五秒钟。如果手势持续执行某些操作,例如使用手势在列表中循环,那么在一段时间内重复手势是可以的 - 用户会明白他们必须继续执行手势才能在列表中移动得更远。这甚至使手势更容易被检测到,因为不需要最后 5 秒的信息,你只需要足够的信息来知道用户现在是否在做手势。

如果您希望用户在一定时间内保持手势,请将其设为固定手势(将手放在某个位置 x 秒比挥手容易得多)。给出一些视觉反馈也是一个很好的主意,比如计时器已经启动。如果用户搞砸了手势(错误的手、错误的位置等)并最终站在那里等待 5 或 10 秒钟等待某事发生,他们不会高兴,但这不是这个问题的真正部分。

从 Kinect 手势开始

从小处开始……真的很小。首先,确保您了解 SkeletonData 类。每个骨架上跟踪了 20 个关节,每个关节都有一个 TrackingState。此跟踪状态将显示 Kinect 是否可以实际看到关节 (Tracked),是否正在根据骨架的其余部分确定关节的位置 (Inferred),或者它是否完全放弃了寻找关节的尝试 (NotTracked) .这些状态很重要。您不想仅仅因为 Kinect 看不到另一条腿并报告其位置为假,就认为用户正站在一条腿上。每个关节都有一个位置,这就是您如何知道用户站立的位置......一点一点。熟悉坐标系。

在您了解骨架数据如何报告的基础知识后,尝试一些简单的手势。当用户将手举过头顶时,在屏幕上打印一条消息。这只需要将每只手与 Head 关节进行比较,并查看在坐标平面中任一只手是否高于头部。在你开始工作之后,再做一些更复杂的事情。我建议尝试滑动 Action (手放在 body 前面,从右到左或从左到右移动一些最小距离)。这需要来自过去帧的信息,因此您必须考虑要存储哪些信息。如果你能做到这一点,你可以尝试在短时间内串联一系列滑动手势并将其解释为波浪。

tl;dr:手势很难。从小事做起,一路向上。不要让用户为一个 Action 做重复的 Action ,这既累人又烦人。包括基于持续时间的手势的视觉反馈。阅读这篇文章的其余部分。

关于c# - Kinect手势分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7763186/

相关文章:

c# - 在 SignalR 2.0 中将消息从服​​务器发送到客户端

c# - 由于 System.Windows.Point/System.Drawing.PointF 差异,在 WPF/Silverlight 和 GDI+ 之间共享库时出现问题

wpf - 在WrapPanel上垂直列出项目并利用多列

visual-studio-2010 - C#VS2010 : how to draw scrolling text using drawstring without flicker

c++ - 删除文本文件中两个特定字符之间的内容

c# - C#中如何解决system.outofmemoryexception

c# - 如何在 C#/Vista 中将鼠标事件传递给我背后的应用程序?

c# - 为什么对单例使用 Lazy<T> 而不是静态工厂类?

wpf - WinRT (C#/XAML) 不模糊缩放

c++ - 创建 C++ 程序时符号加载(源信息剥离)错误