我正在使用Official Kinect SDK做kinect应用程序。
我想要的结果
1)能够识别出身体已经挥舞了5秒。如果有的话做点什么
2)能够识别一只腿倾斜5秒钟。如果有的话做点什么。
有人知道怎么做吗?我正在使用WPF应用程序。
想举一些例子。我是Kinect的新手。
预先感谢您的所有帮助!
参考方案
Kinect为您提供了它所跟踪的骨骼,其余的事情您都要做。基本上,您需要为每个手势创建一个定义,并在每次触发SkeletonFrameReady事件时针对骨骼运行该定义。这不容易。
定义手势
定义手势可能非常困难。最简单(最简单)的手势是在单个时间点上发生的手势,因此不依赖于肢体的过去位置。例如,如果要检测用户何时将手举过头顶,则可以在每个单独的框架上进行检查。更复杂的手势需要考虑一段时间。对于挥舞的手势,您将无法从一个单一的帧中看出一个人是在挥舞还是只是将手举在面前。
因此,现在您需要能够存储过去的相关信息,但是哪些信息是相关的?您是否应该保留最后30帧的图像并针对该图像运行算法? 30帧只能让您获得一秒钟的信息价值。也许60帧?还是您的5秒钟300帧?人类的移动速度并没有那么快,所以也许您可以每隔五帧使用一次,这会使您的5秒钟降为60帧。一个更好的主意是从框架中选择相关信息。对于挥舞的手势,手的当前速度,移动了多长时间,移动了多远等都是有用的信息。
在弄清楚如何获取和存储与手势有关的所有信息之后,如何将这些数字转换为定义?挥舞可能需要一定的最小速度,或者方向(向左/向右而不是向上/向下)或持续时间。但是,此持续时间不是您感兴趣的5秒钟持续时间。该持续时间是假设用户挥手所需的绝对最小值。如上所述,您无法从一帧中确定波浪。您不应从2或3或5中确定波浪,因为那是不够的时间。如果我的手抽动了几分之一秒,您会认为那是波浪吗?可能是一个甜蜜的地方,大多数人都同意从左到右的运动会构成波浪,但我当然不十分了解如何在算法中对其进行定义。
要求用户在一段时间内做某种手势还有另一个问题。很有可能,不管您写的定义如何好,这五秒钟中的每一帧都不是一波。在哪里可以轻松确定某人是否将手举过头了五秒钟(因为可以在单个帧中确定),对于复杂的手势,这样做要困难得多。虽然挥手并没有那么复杂,但仍然显示出这个问题。当您的手在波浪的任一侧改变方向时,它会停止移动几分之一秒。那你还在挥手吗?如果您的回答是肯定的,请更慢地挥手,以便您在任一侧稍稍停顿一下。停顿还是会被视为浪潮吗?在该五秒钟手势中的某个时刻,该定义可能无法检测到波浪。因此,现在您需要考虑对手势持续时间的宽大处理。.如果挥舞手势在最近五秒钟内发生了95%,那是否足够? 90%? 80%?
我要在这里说明的重点是,没有简单的方法可以进行手势识别。您必须仔细考虑手势并确定某种定义,该定义会将一堆关节位置(骨骼数据)变成手势。您需要跟踪过去帧中的相关数据,但要意识到手势定义可能不是完美的。
考虑用户
所以,既然我已经说了为什么很难检测到五秒钟的波浪,请允许我至少对如何做到这一点发表自己的看法:不要。您不应强迫用户在设定的时间段内(五秒钟的波动)重复基于动作的手势。令人惊讶的是,它令人疲劳,而不仅仅是人们对计算机的期望/期望。指向和点击是瞬时的;单击后,我们期望得到答复。没有人希望在打开Minesweeper之前必须先按住五秒钟。如果连续执行某些动作(例如使用手势在列表中循环),则可以在一段时间内重复执行手势-用户将理解他们必须继续执行手势才能在列表中移动更远。这甚至使手势更易于检测,因为您只需要足够的信息来知道用户当前是否正在执行手势,而不需要过去5秒钟的信息。
如果您希望用户将手势保持一定的时间,请使其成为固定手势(将您的手保持在某个位置x秒钟要比挥手容易得多)。提供一些视觉反馈,比如说计时器已经启动,也是一个很好的主意。如果用户拧紧手势(错误的手,错误的位置等)并最终站在那里等待5到10秒钟以等待某件事发生,他们将不会感到高兴,但这并不是这个问题的一部分。
从Kinect手势开始
从小开始..真的很小。首先,请确保您了解SkeletonData类的方法。每个骨骼上跟踪20个关节,每个关节都有一个TrackingState。此跟踪状态将显示Kinect是否可以实际看到关节(已跟踪),是否基于骨骼的其余部分来确定关节的位置(推断),或者是否已完全放弃尝试找到关节(未跟踪)。 。这些状态很重要。您不想仅仅因为Kinect看不到另一条腿并报告虚假姿势而认为用户站在一条腿上。每个关节都有一个位置,这是您如何逐步了解用户站立的位置。熟悉坐标系。
在了解如何报告骨架数据的基础知识之后,尝试一些简单的手势。当用户将手举过头顶时,将消息打印到屏幕上。这仅需要将每只手与“头部”关节进行比较,并查看在坐标平面中任一只手是否高于头部。完成工作后,继续进行一些更复杂的工作。我建议尝试滑动动作(将手放在身体前方,从右到左或从左到右移动一些最小距离)。这需要过去框架中的信息,因此您必须考虑要存储哪些信息。如果可以正常工作,则可以尝试在短时间内串出一系列滑动手势,并将其解释为挥手动作。
tl; dr:手势很难。从小处着手,逐步向上。不要让用户为单个动作重复动作,这很累人又烦人。包括基于持续时间的手势的视觉反馈。阅读这篇文章的其余部分。
WPF WebBrowser甚至使用ObjectForScripting在单独的线程上锁定UI - javascript在与WPF Web浏览器控件绑定的ObjectForScripting上调用方法时,网页UI锁定会出现一个奇怪的问题。进一步的研究使我们意识到整个UI(包括WPF应用程序而不是WebBrowser)都已锁定。使用的技术是带有Caliburn.Micro和Autofac的WPF。我在COM可见类上使用方法来推送到Caliburn.Micro提供的事件聚合器。进…
WPF MVVM中的动态TabControl - c#我几周前开始使用WPF(在C#中),现在我需要一些高级帮助来使用tabcontrol。首先,我正在使用MVVM(模型视图ViewModel)模式来设计我的应用程序,并且我有一个约束,即试图不要在文件(初始化xaml文件)后面的代码中添加代码。现在,我的问题是在MainWindow视图(窗口)中动态创建新的tabItem,当单击按钮(例如“新建选项卡”按钮)时…
WPF-将窗口大小设置为子用户控件大小 - c#我有一个选项卡控件,该控件动态地填充有包含各种大小的用户控件的选项卡。打开选项卡后,我希望窗口自动调整大小,使其在活动用户控件下有意义。有一种干净的方法可以做到这一点吗?我正在使用标准的mvvm模式。 参考方案 在Window类上使用SizeToContent属性。<Window x:Class="WpfApplication1.MainWi…
获取ListBoxItem的索引-WPF - c#如何获取ListBoxItem的索引?ListBox通过XmlDataProvider绑定到XML节点的集合。 参考方案 我有一个类似的问题,得到了回答here基本上,您将ListBox的AlternationCount设置为非常高的值,并绑定到每个项目上的AlternationIndex<ListBox AlternationCount="…
在Visual Studio Proff中调试本机代码 - c#我们在这里使用的解决方案包括C#中的一个项目和C中的另一个项目。是否可以在Visual Studio中调试c代码? c#参考方案 当然,如果您有源代码,请从中创建一个项目,作为调试进行编译(添加断点,监视...)并进行调试。