手势识别Kinect

来源:互联网 发布:js拆分字符串 编辑:程序博客网 时间:2024/05/16 12:38
Microsoft Kinect SDK 并没有包含手势识别引擎。因此需要开发者来定义和手势识别。从 SDK
的 Beta 版放出以来,一些第三方开发者创建的手势引擎已初见端倪。但是,微软没有将他们作为标
准的引擎。看来这可能还要等微软将手势识别引擎添加到 SDK 中来,或者指明可替代的解决方案。
本节对手势识别技术进行了简单介绍,希望能够帮助开发者在标准的手势识别引擎出来之前,可以自
己动手开发手势识别引擎。
手势识别相对来说可以简单也可以很复杂,这取决与要识别的手势。有三种基本的方法可以用来
识别手势:基于算法,基于神经网络和基于手势样本库。每一种方法都有其优缺点。开发者具体采用
那种方法取决与待识别的手势、项目需求,开发时间以及开发水平。基于算法的手势识别相对简单容
易实现,基于神经网络和手势样本库则有些复杂。
基于算法的手势识别
算法是解决软件开发中几乎所有问题的最基本方法。 使用算法的基本流程就是定义处理规则和条
件,这些处理规则和条件必须符合处理结果的要求。在手势识别中,这种算法的结果要求是一个二值
型对象,某一手势要么符合预定的手势要么不符合。使用算法来识别手势是最基本的方法,因为对于
有一点编程能力的开发这来说,手势识别的代码易于理解,编写,维护和调试。
但是,最简单直接的方法也有其缺点。算法的简单性限制了其能识别到的手势的类别。对于挥手
(wave)识别较好的算法不能够识别扔(throw)和摆(swing)动作。前者动作相对简单和规整,后者则更
加细微且多变。可能能够写一个识别摆动(swing)的算法,但是代码可能比较费解和脆弱。
算法还有一个内在的扩展性问题。虽然一些代码可以重用,但是每一种手势必须使用定制的
算法来进行识别。随着新的手势识别算法加入类库,类库的大小会迅速增加。这就对程序的性能产生
影响,因为需要使用很多算法来对某一个手势进行识别以判断该手势的类型。
最后,每一个手势识别算法需要不同的参数,例如时间间隔和阈值。尤其是在依据流程识别特定
的手势的时候这一点显得尤其明显。开发者需要不断测试和实验以为每一种算法确定合适的参数值。
这本身是一个有挑战也很乏味的工作。然而每一种手势的识别有着自己特殊的问题。
4.2 基于神经网络的手势识别
当用户在做手势时,手势的形式并不总是足够清晰到能够判断用户的意图。例如跳跃手势,
跳跃手势就是用户短暂的跳起来,脚离开地面。这个定义不能够提供足够的信息来识别这一动作。
咋一看,这个动作似乎足够简单,使得可以使用算法来进行识别。首先,考虑到有很多种不
同形式的跳跃: 基本跳跃 (basic jumping) 、 跨栏(hurdling)、 跳远(long jumping)、 跳跃(hopping),
等等。但是这里有一个大的问题就是,由于受到 Kinect 视场区域的限制,不可能总是能够探测到地
板的位置, 这使得脚部何时离开地板很难确定。 想象一下, 用户在膝盖到下蹲点处弯下, 然后跳起来。
手势识别引擎应该认为这是一个手势还是多个手势:下蹲或 下蹲跳起或者是跳起?如果用户在蹲下
的时间和跳跃的时间相比过长,那么这一手势可能应被识别为下蹲而不是跳跃。
看到这些,最开始对跳跃的定义就会变得模糊。这一姿势很难定义清楚,使得不能够通过定
义一些算法来进行识别,同时这些算法由于需要定义过多的规则和条件而变得难以管理和不稳定。使
用对或错的二值策略来识别用户手势的算法太简单和不够健壮,不能够很好的识别出类似跳跃,下蹲
等动作。
神经网络的组织和判断是基于统计和概率的,因此使得像识别手势这些过程变得容易控制。
基于什么网络的手势识别引擎对于下蹲然后跳跃动作,80%的概率判断为跳跃,10%会判定为下蹲。
除了能够识别复杂和精细的手势,神经网络方法还能解决基于算法手势识别存在的扩展性问
题。 神经网络包含很多神经元, 每一个神经元是一个好的算法, 能够用来判断手势的细微部分的运动。
在神经网络中,许多手势可以共享神经元。但是每一中手势识别有着独特的神经元的组合。而且,神
经元具有高效的数据结构来处理信息。这使得在识别手势时具有很高的效率。
使用基于神经网络进行手势识别的缺点是方法本身复杂。虽然神经网络以及在计算机科学中
对其的应用已经有了好几十年,建立一个好的神经网络对于大多数程序员来说还是有一些困难的。大
多数开发者可能对数据结构中的图和树比较熟悉, 而对神经网络中尺度和模糊逻辑的实现可能一点都
不了解。这种缺乏建立神经网络的经验是一个巨大的困难,即使能够成功的构建一个神经网络,程序
的调试相当困难。
和基于算法的方法相比,神经网络依赖大量的参数来能得到精确的结果。参数的个数随着神
经元的个数增长。每一个神经元可以用来识别多个手势,每一个神经远的参数的变化都会影响其他节
点的识别结果。配置和调整这些参数是一项艺术,需要经验,并没有特定的规则可循。然而,当神经
网络配对机器学习过程中手动调整参数,随着时间的推移,系统的识别精度会随之提高。
基于样本的识别
基于样本或者基于模版的手势识别系统能够将人的手势和已知的手势相匹配。 用户的手势在模板
库中已经规范化了,使得能够用来计算手势的匹配精度。有两种样本识别方法,一种是存储一系列的
点,另一种方法是使用类似的 Kinect SDK 中的骨骼追踪系统。在后面的那个方法中,系统中包含一
系列骨骼数据和景深帧数据, 能够使用统计方法对产生的影像帧数据进行匹配以识别出已知的帧数据
来。
这种手势识别方法高度依赖于机器学习。识别引擎会记录,处理,和重用当前帧数据,所以随着
时间的推移,手势识别精度会逐步提高。系统能够更好的识别出你想要表达的具体手势。这种方法能
够比较容易的识别出新的手势,而且较其他两种方法能够更好的处理比较复杂的手势。但是建立这样
一个系统也不容易。首先,系统依赖于大量的样本数据。数据越多,识别精度越高。所以系统需要大
量的存储资源和 CPU 时间的来进行查找和匹配。其次系统需要不同高度,不同胖瘦,不同穿着(穿
着会影响景深数据提取身体轮廓)的样本来进行某一个手势。
识别常见的手势
选择手势识别的方法通常是依赖于项目的需要。如果项目只需要识别几个简单的手势,那么使用
基于算法或者基于神经网络的手势识别就足够了。对于其他类型的项目,如果有兴趣的话可以投入时
间来建立可复用的手势识别引擎,或者使用一些人家已经写好的识别算法,接下来本文介绍几种常用
的手势,并演示如何使用算法的方法来识别他们,手势识别的另外两种方法由于其复杂性本文不做介
绍。
不论选择哪种手势识别的方法,都必须考虑手势的变化范围。系统必须具有灵活性,并允许某一
个手势有某个范围内的变动。很少有人能够每次都做一模一样的手势。例如,考虑周伯通当前左右手
画圆圈这个手势,重复这一手势 10 次,圆形的中心每次都在一个点吗,圆形的起点和重点每次都在
相同的地方吗?每次画圆的时长都一样吗?然后使用右手做这个动作,最后比较结果。或者拉几个朋
友或者家人来做,然后观察。也可以站在镜子前面看自己做,或者使用录像设备录下来再看。技巧就
是对于某一手势,让尽可能多的人来做,然后试图标准化这一手势。手势识别一个比较好的方式就是
关注手势最核心的部分而不是哪些外在的细枝末节。
挥动(wave)手势
只要玩过 Xbox 上的体感游戏,可能都使用过挥手这个手势。挥手这一手势不论年龄大小都能够
做的一个简单动作。这是一个友好的,快乐的手势,人们通常挥手或者招手来打招呼或者道别。在应
用开发的上下文中,挥手手势通常告诉应用程序已经准备好了,可以开始体验应用了。
挥手是最简单最基本的手势。使用算法方法能够很容易识别这一手势,但是之前讲到的任何方法
也能够使用。虽然挥手是一个很简单的手势,但是如何使用代码来识别这一手势呢?读者可以在镜子
前做向自己挥手,然后仔细观察手的运动,尤其注意观察手和胳膊之间的关系。继续观察手和胳膊之
间的关系,然后观察在做这个手势事身体的整个姿势。有些人保持身体和胳膊的不动,使用手腕左右
移动来挥手。有些人保持身体和胳膊不动使用手腕前后移动来挥手。可以通过观察这些姿势来了解其
他各种不同挥手的方式。
XBOX 中的挥手动作定义为:从胳膊开始到肘部弯曲。用户以胳膊肘为焦点来回移动前臂,移动
平面和肩部在一个平面上,并且胳膊和地面保持平行,在手势的中部(下图 1),前臂垂直于后臂和地
面。下图展示了这一姿势。
从图中可以观察得出一些规律,第一个规律就是,手和手腕都是在肘部和肩部之上的,这也是大
多是挥手动作的特征。这也是我们识别挥手这一手势的第一个标准。
第一幅图展示了挥手这一姿势的中间位置,前臂和后臂垂直。如果用户手臂改变了这种关系,前
臂在垂直线左边或者右边,我们则认为这是该手势的一个片段。对于挥手这一姿势,每一个姿势片段
必须来回重复多次,否则就不是一个完整的手势。这一运动规律就是我们的第二个准则:当某一手势
是挥手时,手或者手腕,必须在中间姿势的左右来回重复特定的次数。使用这两点通过观察得到的规
律,我们可以通过算法建立算法准则,来识别挥动手势了。
算法通过计算手离开中间姿势区域的次数。 中间区域是一个以胳膊肘为原点并给予一定阈值的区
域。算法也需要用户在一定的时间段内完成这个手势,否则识别就会失败。这里定义的挥动手势识别
算法只是一个单独的算法,不包含在一个多层的手势识别系统内。算法维护自身的状态,并在识别完
成时以事件形式告知用户识别结果。挥动识别监视多个用户以及两双手的挥动手势。识别算法计算新
产生的每一帧骨骼数据,因此必须记录这些识别的状态。
0 0