(手势触摸IC)设计的基础概念以及手势辨认的发展过程
您好,欢迎您进入深圳劲锐佳科技有限公司!
网络营销热线
0755-83088967
  • 1
  • 2
  • 3
接洽我们

接洽我们

官方网站:
runbangw.com
接洽电话:
0755-83088967 83088481
接洽传真:
0755-83088481
电子邮箱:
info@jinrui-tech.com
接洽地址:
深圳市龙华新区油松路天汇大厦C栋205室
当前地位: 首页 » 消息中心 » 消息内容 » 企业消息
(手势触摸IC)设计的基础概念以及手势辨认的发展过程

(手势触摸IC)设计的基础概念以及手势辨认的发展过程

类别:

像点击(clicks)是GUI平台的核心,轻点(taps)是触摸平台的核心那样,手势(gestures)是Kinect利用程序的核心••。和图形用户界面中的数字交互不同,手势是现实生活中存在的动作••。如果没有电脑我们就不需要鼠标,但是没了Kinect,手势依然存在••。从另一方面讲,手势是日常生活中人与人之间相互交换的一部分••。手势能够加强演讲的说服力,能够用来强协调传递情绪••。像挥手(waving)或者指导(pointing)这些手势都是某种无声的演讲••。

Kinect利用程序的设计和开发者的任务就是将这些现实生活中存在的手势映射到盘算机交互中去以转达人的想法••。尝试从鼠标或触摸式的GUI设计移植基于手势的自然交互界面要做很多工作••。借鉴过去30多年来对于这一概念的研究,以及从一些Kinect for Xbox的体感游戏中获取一些设计理念,盘算机工程师和交互设计师一起为Kinect创立了一系列新的手势库••。

本文将会介绍用户体验的一些知识,并讨论如何将手势利用到Kinect利用程序中••。我们将展现Kinect如何作为自然交互界面(Natural User )的人机交互模型的一部分••。我们将讨论一些具体的应用Kinect来进行手势辨认及交互的例子••。更重要的是,将会展现一些已经作为Kinect手势辨认库中的手势••。

1. 什么是手势

在许多不同的学科中,手势(gesture)有着其奇特的含义,可能这些含义之间有某些异同••。在艺术领域,手势被用来转达舞蹈中最富表现力的部分,特别是在亚洲舞蹈艺术中,手势被作为某些宗教符号或者象征••。在交互设计领域,在基于触摸的自然交互界面中手势和操控有很大差别••。

以上这些阐明手势在不同的学科领域都有自己奇特的含义••。在学术领域都试图对手势定义一个抽象的概念••。在用户体验设计领域应用最广泛的关于手势的定义实在Eric Hulteen 和Gord Kurtenbach 1990年发表的一篇名为人机交互中的手势(Gestures in Human-Computer Communication),定义如下:”手势是身材的运动,他包含一些信息••。挥手道别是一种手势••。敲击键盘不是手势,因为用手指的运动去敲击按键没有被视察,也不重要,他只表达的键盘被按下这一动作••。(A gesture is a motion of the body that contains information. Waving goodbye is a gesture. Pressing a key on a is not a gesture because the motion of a finger on its way to hitting a key is neither observed nor significant. All that matters is which key was pressed)”

这个定义既解释了什么是手势也解释了什么不是手势••。像这样的下一个正式的定义通常有两个方面的艰苦,既要避免太具体也要避免太抽象••。如果一个定义太具体-如,定义某项技巧-可能会随着UI技巧的变更会变得含混不清••。作为一种学术定义而不是以常见的用法为基础的定义,它也必须足够一般,并且符合或者说宽大的研究机构先前已发表在HCI的研究成果及艺术中符号学••。另一方面,定义过于宽泛,也会有有无关紧要的风险:如果一切都是一种姿势,那么就什么都不是了••。

Eric Hulteen 和Gord Kurtenbach关于手势的定义的中心在于手势能够用来交换,手势的意义在于讲述而不是履行••。

有趣的是将语言和行动引入到人机交互接口中来,这是一种彻底的变更••。我们与盘算机交互语音变为无声的语言(mute):我们通过指导和手势而不是语言与盘算设备进行沟通••。当和盘算机进行交互时,我们点击键盘按键或触摸屏幕••。我们似乎更爱好这种情势的静音通信即使当前的技巧能够支撑更简略的语音指令••。我们没有操作(manipulation)的力量,和虚拟的对象而不是真实的物体进行交互,因而没有持久性••。运动成为纯粹的手势••。

基于Eric Hulteen 和Gord Kurtenbach的定义,我们都明确什么是 UI 操作 ——暂时不是一种手势 ——懂得什么是手势以及手势表现"重大"行动或者符号仍然有很大的艰苦••。移动交互的含义是什么?手势进行沟通和语言进行沟通的最明显不同是什么?我们做手势的象征意义往往很抽象简略••。

在人机交互领域,手势通常被作为转达一些简略的指令而不是交换某些事实¶••⊿描写问题或者陈述想法••。应用手势操作电脑通常是命令式的,这通常不是人们应用手势的目标••。例如,挥手(wave)这一动作,在现实世界中通常是打招呼的一种方法,但是这种打招呼的方法在人机交互中却不太常用••。通常第一次写程序通常会显示“hello”,但我们对和电脑打招呼并不感兴趣••。

但是,在一个繁忙的餐馆,挥手这一手势可能就有不同的含义了••。当向服务员招收时,可能是要引起服务员注意,需要他们供给服务••。在盘算机中,要引起盘算机注意有时候也有其特别意义,比如,盘算机休眠时,一般都会敲击键盘或者移动鼠标来唤醒,以提示盘算机“注意”••。当应用Kinect时,可以应用更加直观的方法,就行少数派报告阿汤哥那样,抬起双手,或者简略的朝盘算机挥挥手,盘算机就会从休眠状态唤醒••。

在人机交互领域,手势通常有一些含义,表现有意让某些事情产生••。手势是一种指令••。当通过鼠标或者触控板去点击UI界面上的按钮时,我们盼望按钮会触发其背后的事件••。通常,按钮上会有一个标签来唆使按钮的功效如:开端¶••⊿取消¶••⊿打开¶••⊿关闭••。我们的手势操作就是想要实现这些事件••。

上面的定义中的第一点可以得出,手势的另一个特点是比较随便(arbitrary)••。手势有限定的领域,那么在该领域之外没有任何意义••。令人惊讶的是除了指向(pointing)和耸肩(shurg),人类学家没有创造任何东西我们可以称之为一种通用的手势••。然而,在盘算机的UI中,指向(pointing)通常被认为是直接操作因为它牵涉到跟踪,同时耸肩的含义太奥妙而不好辨识••。因此,我们想要应用的任何Kinect手势必须基于利用程序的用户 和利用程序的设计和开发者之间就某种手势代表的含义达成一致••。

因为手势是任意的(arbitrary)所以他们也是基于约定的(conventional)••。利用程序的设计者必须告诉用户正在应用的手势的意义,或者是这些手势是约定俗称大家都知道的••。此外,这些约定不是基于语言文化,而是对已断定的技巧规矩••。我们知道如何应用鼠标 (行动学习) 并不是因为这是我们已经从我们的文化导入的东西,而是因为这是基于特定的图形用户界面的跨文化约定••。同样地,我们知道如何点击或滑动智能手机,不是因为这些都是文化的约定,而是因为这些都是跨文化自然用户界面项约定••。有趣的是,我们在必定程度上知道如何点击平板电脑,因为我们以前学习了如何应用鼠标单击••。技巧约定之间可以相互转化,这是因为语言和手势可以通过不同的语言和文化之间来转换••。

然而,手势的这种任意性和基于约定的特征也带来了曲解性(misunderstanding),这是在设计任何用户界面,尤其是像Kinect这样的没有任何预先设定好的操作约定的用户界面时需要关注的风险••。就像在有些国家,点头表现否定摇头表现可能••。手势,或者任何身材的运动,都有可能产生曲解••。

总之,在人机交互领域,手势是:

  • 表达一种简略的命令

  • 天生有随便性

  • 基于某种协议

  • 可能被曲解

注意:实际的直接操作(manipulation)不是手势••。

2. 自然交互界面(NUI)

讨论手势而不讨论自然用户界面显然不完整••。自然用户界面是一系列技巧的合计,他包含:语音辨认,多点触控以及类似Kinect的动感交互界面,他和Windows和Macs操作系统中鼠标和键盘交互这种很常见图形交互界面不同••。就像图像交互界面和之前的命名行交互界面不同那样••。

自然交互界面自然在哪儿呢?早期自然交互界面的发起者认为交互界面的设计应当对用户非常直观,应用用户先天就会的行动来进行交互操作••。他的目标是不需要操作由图标和菜单构成的基于GUI 的利用程序界面,因为这种界面通常具有陡峭的学习曲线••。相反,理想化的状态是,用户应当能够走到利用程序前面,就能够开端应用它••。在过去的几年里随着触摸功效的智能手机和平板电脑的风行,逐渐代替了键盘鼠标,当我们看到孩子们开端走到任何触摸屏设备面前,用手去触摸它,期待它的响应,在这一点上看这一理念已经实现••。

虽然自然用户界面的自然性似乎是直接操作的最佳写照,当应用手指来进行触摸交互时,先天自然和后天学习行动之间的对峙被打破••。一些手势,如轻触屏幕,在某种意义上就是先天就会的动作••。其他的动作比如说双击,获得点击然后拖拉等,没有先天就会••。而且随着不同的设备制作商开端支撑不同触摸手势,为了使得雷同的手势在不同的触摸平台上有雷同的意义和行动,为某些手势定义一些约定显得更加重要••。

自然用户界面(NUI)的自然性更多的是一种相对自然的概念••。对于NUI的更现代的懂得受Bill Buxton所影响••。他认为NUI界面的设计充分利用了用户预先就会的技巧,用户和UI进行交互感到很自然,使得他们甚至忘了是从哪里学到这些和UI进行交互所需的技巧的••。换句话说,第一次操作时,我们不记得我们曾经学过这些知识••。例如,轻点(tap)这个手势早平板电脑和手机中应用的很频繁,这个技巧是从我们之前在传统的人机交互界面上应用鼠标来指向并点击某一个界面上的元素学来的••。点击(click)和轻点(tap)的最重要差别在于,点击需要鼠标,对于触摸屏,不需要额外的设备,只需要用手指轻轻触摸一下屏幕就可以了••。

这引出了自然用户界面的另一个特点••。用户和盘算机之间的交互看起来不需要任何媒介,这种相互作用的媒介是不可见的••。例如,在语音辨认界面中,人机交互是通过具有复杂电子过滤去噪的麦克风实现的,其内部有解析发音语义单元的各种算法,将这些语义传递给其它软件来进行将特定的短语解释为命令,并将该命令映射到某种软件功效操作••。但是,内部的这一切,对用户是不可见的••。当用户对盘算机发出这样的命令,"嘿,注意我",她会认为盘算机会像类似大多数人的本能那样的响应这个命令••。

自然用户界面的 依附于先验知识和不需要媒介的交互这两个特点是每一种NUI界面的共同特点,其他方面如触摸,语音和动态交互界面则因设备的不同而各异••。目前,大多数关于NUI的设计都是基于多点触控体验的••。这就是为什么前面对于手势的标准定义是那样定义的••。它是将多点触摸的场景进行修正并将手势和操作区离开来••。

关于手势(gesture)和操作(manipulation)的争辩也存在于语音交互界面中,命令等同于手势,语音等同于直接操作,在动态交互界面中,将手或者身材追踪展现在可视化界面上手和身材的运动等同于直接操作••。自由情势的运动像挥手这一动作就属于手势••。

但是Kinect还有第三种交互界面,他和触摸和语音交互不同••。那就上一篇文章中所讲的姿势(pose),姿势是身材的某一部分和其他部分之间的一种静态关系,他不是运动的••。Kinect中的姿势和日常生活中的姿势是一样的,例如,左臂伸出45度表现将当前的窗口变为运动的交互窗体,右臂伸出45度或者135度表现垂直滚动工具栏••。

另外,交互方法可以从一种类型的交互界面转换到另外一种交互界面••。以按钮为例,按钮其实就是一个符号,这是一个先验的图形用户界面••。从最基础的功效来讲,按钮就是一个通过鼠标点击在一个可视化元素的文字或者图像上触发一些命令的工具••。在过去15年,按钮被作为人机交互界面的一个集成部分,被转换到多点触摸界面,以及Kinect用户界面中来••。

自然用户界面设计师所寻求的是的是自然,按钮恰好供给了这一点••。但是按钮在每一种用户界面中的转换都面临着一些寻衅••。

图形用户界面中按钮的一个通常的特点是他供给了一个悬浮状态来唆应用户光标已经悬停在的按钮上方的正确地位••。这种悬浮状态将点(click)这个动作离散开来••。悬浮状态可认为按钮供给一些额外的信息••。当将按钮移植到触摸屏交互界面时,按钮不能供给悬浮状态••。触摸屏界面只能响应触摸••。因此,和电脑上的图像用户界面相比,按钮只能供给“击”(click)操作,而没有“点”(point)的能力••。

当将按钮移植到基于Kinect的用户界面上时,按钮的行动就变得更加特别了••。基于Kinect的图形界面中,按钮的行动和触摸界面中的刚好相反,他只供给了悬浮(hover)的“点”(point)的能力,没有“击”(click)的能力••。按钮这种更令用户体验设计者感到沮丧的弱点,在过去的几年里,迫使设计者不断的对Kinect界面上的按钮进行改良,以供给更多奥妙的方法来点击视觉元素••。这些改良包含:悬停在按钮上一段时间¶••⊿将手掌向外推(笨拙地模仿点击一个按钮的行动)等••。

虽然触摸界面也有手势,但Kinect 界面有些互动不是手势,不过软件的开发和设计者偏向于以 Kinect 手势操作作为交互界面••。这似乎是因为应用手势作为物理操作是 Kinect 利用程序的最大的特点••。与此相反的是,触摸界面的突出特点是直接操作••。虽然可能不正确,人们通常将自然交互界面划分为三类:语音交互界面,触摸交互界面和手势交互界面••。

然而,在关于Kinect的相干介绍文档中,你会创造有时候姿势(pose)和操作(manipulation)都被描写为手势••。这些都没有错••。要记住的是,当我们讨论Kinect中的一些术语,如挥手(wave),滑动(swipe),我们会作为纯粹的手势,而姿势和操控只有在隐喻意义上才称之为手势••。

以上的讨论都很重要,因为我们会进一步设计Kinect互动的语意,我们将最终移除从其他图形界面上借鉴过来的关于按钮的语意,然后尝试建立基于Kinect的先验的语意••。挥手(wave)这是Kinect中纯粹的手势,是最早的这种尝试••。乔治亚技巧研究所的研究人员正在利用 Kinect 来解释美国手语••。相反,其他研究人员,正在利用 Kinect 解释身材语言——另一种预先形成的手势和姿势的沟通••。诸如此类的研究可以视为对于NUI的第二层研究••。这些逐渐接近了最初NUI人机交互的原始的理想,不只是看不见,而且NUI能够自适应以懂得我们的行动,而不是迫使我们懂得我们和电脑的人机交互••。

3. 手势从哪里来

在手势交互界面中,纯粹的手势,姿势和追踪以及他们之间的组合构成了交互的基础术语••。对于Kinect来说,目前可以应用的有8个通用的手势:挥手(wave),悬浮按钮(hover ),磁吸按钮(magnet button),推按钮(push button),磁吸幻灯片(magnetic slide),通用暂停(universal pause),垂直滚动条(vertical scrolling)和滑动(swipping)••。其中的一些术语是微软自己引入的,有一些是游戏代理商设计的,还有一些是Kinect for PC开发人员为了开发利用而引入的••。

很少情况下会为人际交互界面术语进行定制••。通常要将这8种手势区离开来,并在一些利用中通用也不常见••。类似的情况在web术语和手机手势中设计新的界面时也会遇到,其中只有部分的设计能够变成标准••。在网页设计领域,走马灯和光标动画风行一时,并在一片鄙夷声中迅速消散••。在手机设计领域由于苹果公司在触摸屏领域的早期地位这种术语得到了很好的规范••。苹果引入了一些触摸手势术语,如轻点(tap),点住不放(tap and hold),滑动swipe及pinch••。

 

 

交互术语形成规范有几个障碍••。第一个就是为了获得利益而避免标准化••。在90年代后期的浏览器大战中,尽管各大厂商在口头上说标准化协议很重要,但是在浏览器开发上依旧不停的开发自己的HTML版本,以吸引开发者应用他们的技巧••。设备制作商可以利用市场占领率的优势来锁定消费者,通过在他们的手机上实现自己定义语意的触屏,来推行自己的手势操作••。这些都是不自然的行动,因为不同厂商对于同一手势的语意都不同,并且他们看起来不自然,应用不同厂商的产品需要再学习••。

另一种形成规范化的障碍是高低文手势的专利••。例如,苹果公司不能对“滑动”(swipe)操作申请专利,但是它可以对“滑动解锁手机”这个手势申请专利,这使得其他公司需要应用这一技巧或者设计理念时要么给苹果公司支付专利费,要么将苹果告上法庭以避免专利费,或则干脆不应用这一高低文手势••。如果不应用这一高低文手势,那么产品就损坏了之前我们学习到应用很自然的方法滑动解锁手机,音乐播放器,平板电脑等这一约定了••。

最后一个障碍是,设计一个手势很艰苦••。手势术语会见对一些App Store中手机利用程序和YouTube中视频利用所遇到的一些问题:人们要么会要么不会••。手势需要思考如何定义的简略使得人们能够去用,这就是长尾理论留下来的问题••。

那么什么样的手势术语才是好的呢••。如果一个手势易于应用,那么他就被认为是设计良好的••。在交互设计中,易用性有两个方面:可用(affordance)和反馈(feedback)••。反馈就是说用户知道当前正在进行的操作••。在网页中,点击按钮会看到按钮有一点偏移,这就表现交互成功••。鼠标按键按下时的声音在某种意义上也是一种反馈,他表现鼠标在工作••。对于Winodw Phone Metro作风的界面上的磁贴,开发这认为这些按钮应当足够大,以容下大面积的触摸区域,但是他们也认为过大的触摸区域会使得用户触摸到区域外面也会触发注册的事件••。另外,状态信息或者确认对话框会在利用程序中弹出以提示用户产生了一些事情••。在 Xbox 的仪表板中,应用Kinect器产生的光标悬停在的热门上开端动画播放••。

如果说反馈产生在操作进行中或者之后,那么可用性(affordance)就产生在操作之前了••。可用性就是一种提示或者领导,告诉用户某一个可视化元素是可以交互的,唆应用户该元素的用处••。在GUI交互界面中,按钮是能够最好的完成这些理念的元素••。按钮通过文字或者图标提示来履行一些函数操作••。GUI界面上的按钮通过悬浮状态可以提示用户其用处••。最好的可用性-可能有点绕圈-就是约定俗成••。用户知道某一个可视化元素的用处,因为之前在其他利用中应用过类似的可视化控件,或者是在其他设备中履行过类似的操作••。但是,这一点对于基于Kinect的手势交互界面来说有点艰苦,因为一切都是新的••。

通常的做法就是应用借用其他类型交互界面中的约定••。在触摸交互界面中,一个轻点(tap)手势和通常的鼠标点击是等同的••。响应轻点事件的两个可视化元素,图标和按钮,也被设计的和传统的GUI界面上的图标和按钮一样,来达到提示用户该元素的作用这一目标••。Kinect也应用按钮和图标来使得用户能够更加容易应用••。因为Kinect基础上是基于”点”(pointing)而原生不支撑“击”(clicking)••。在此之前,软件界面设计者和开发者的消费了很多精力来对手势交互界面进行定制以实现“击”这一动作••。

和触摸交互界面不一样,手势交互界面可以从社会中人的一般手势中借用一些手势操作••。这就使得挥手(wave)成为Kinect利用程序的经典手势••。因为这一姿势和现实生活中的姿势有象征性接洽使得非常容易懂得和应用••。轨迹追踪,虽然在技巧上不是手势,但是他是另一个在现实生活中和指导有接洽的术语••。当在电视机或者显示器前挥动手时,好的Kinect利用程序应当能够追踪到手的运动,并显示一个光标随着手一起运动••。当我们在现实生活中指导物体时,Kinect中的手部追踪显示的手形图标的反馈使得程序更加易用••。

目前,现实生活中的易用性手势在Kinect交互界面中用的比较少,大部分的易用性都是从传统的GUI界面上的可用性移植过来的••。随着时间的转变,这一点会得到改良••。在触摸屏设备上新的手势通过在传统的已经建立的约定中添加手指来形成••。两指轻点和一指轻点有些不同,应用两个手指或者多个手指进行滑动有其奇特的含义••。最终,触摸手势全部由手指完成••。另一方面,真正的手势用户界面,有一个近乎无穷的语意库,使得我们可以基于现实生活中相干联的手势进行改良••。

本文接下来从理论到实现,讨论如何实现手势辨认,并展现了Kinect中八中基础手势中的挥手(wave)手势的辨认••。

4. 实现手势辨认

Microsoft Kinect SDK并没有包含手势辨认引擎••。因此需要开发者来定义和手势辨认••。从SDK的Beta版放出以来,一些第三方开发者创立的手势引擎已初见端倪••。但是,微软没有将他们作为标准的引擎••。看来这可能还要等微软将手势辨认引擎添加到SDK中来,或者指明可替代的解决方案••。本节对手势辨认技巧进行了简略介绍,盼望能够赞助开发者在标准的手势辨认引擎出来之前,可以自己动手开发手势辨认引擎••。

手势辨认相对来说可以简略也可以很复杂,这取决与要辨认的手势••。有三种基础的方法可以用来辨认手势:基于算法,基于神经网络和基于手势样本库••。每一种方法都有其优毛病••。开发者具体采用那种方法取决与待辨认的手势¶••⊿项目需求,开发时间以及开发程度••。基于算法的手势辨认相对简略容易实现,基于神经网络和手势样本库则有些复杂••。

4.1 基于算法的手势辨认

算法是解决软件开发中几乎所有问题的最基础方法••。应用算法的基础流程就是定义处理规矩和条件,这些处理规矩和条件必须符合处理成果的请求••。在手势辨认中,这种算法的成果请求是一个二值型对象,某一手势要么符合预定的手势要么不符合••。应用算法来辨认手势是最基础的方法,因为对于有一点编程能力的开发这来说,手势辨认的代码易于懂得,编写,掩护和调试••。

但是,最简略直接的方法也有其毛病••。算法的简略性限制了其能辨认到的手势的类别••。对于挥手(wave)辨认较好的算法不能够辨认扔(throw)和摆(swing)动作••。前者动作相对简略和规整,后者则更加细微且多变••。可能能够写一个辨认摆动(swing)的算法,但是代码可能比较费解和软弱••。

算法还有一个内在的扩大性问题••。虽然一些代码可以重用,但是每一种手势必须应用定制的算法来进行辨认••。随着新的手势辨认算法参加类库,类库的大小会迅速增长••。这就对程序的性能产生影响,因为需要应用很多算法来对某一个手势进行辨认以断定该手势的类型••。

最后,每一个手势辨认算法需要不同的参数,例如时间间隔和阈值••。尤其是在根据流程辨认特定的手势的时候这一点显得尤其明显••。开发者需要不断测试和实验认为每一种算法断定合适的参数值••。这本身是一个有寻衅也很乏味的工作••。然而每一种手势的辨认有着自己特别的问题••。

4.2 基于神经网络的手势辨认

当用户在做手势时,手势的情势并不总是足够清楚到能够断定用户的意图••。例如跳跃手势,跳跃手势就是用户短暂的跳起来,脚离开地面••。这个定义不能够供给足够的信息来辨认这一动作••。

咋一看,这个动作似乎足够简略,使得可以应用算法来进行辨认••。首先,考虑到有很多种不同情势的跳跃:基础跳跃(basic jumping)¶••⊿ 跨栏(hurdling)¶••⊿ 跳远(long jumping)¶••⊿ 跳跃(hopping),等等••。但是这里有一个大的问题就是,由于受到Kinect视场区域的限制,不可能总是能够探测到地板的地位,这使得脚部何时离开地板很难断定••。想象一下,用户在膝盖到下蹲点处弯下,然后跳起来••。手势辨认引擎应当认为这是一个手势还是多个手势:下蹲或 下蹲跳起或者是跳起?如果用户在蹲下的时间和跳跃的时间相比过长,那么这一手势可能应被辨认为下蹲而不是跳跃••。

看到这些,最开端对跳跃的定义就会变得含混••。这一姿势很难定义明确,使得不能够通过定义一些算法来进行辨认,同时这些算法由于需要定义过多的规矩和条件而变得难以管理和不稳固••。应用对或错的二值策略来辨认用户手势的算法太简略和不够硬朗,不能够很好的辨认出类似跳跃,下蹲等动作••。

神经网络的组织和断定是基于统计和概率的,因此使得像辨认手势这些过程变得容易••。基于什么网络的手势辨认引擎对于下蹲然后跳跃动作,80%的概率断定为跳跃,10%会判定为下蹲••。

除了能够辨认复杂和精致的手势,神经网络方法还能解决基于算法手势辨认存在的扩大性问题••。神经网络包含很多神经元,每一个神经元是一个好的算法,能够用来断定手势的细微部分的运动••。在神经网络中,许多手势可以共享神经元••。但是每一中手势辨认有着奇特的神经元的组合••。而且,神经元具有高效的数据结构来处理信息••。这使得在辨认手势时具有很高的效率••。

应用基于神经网络进行手势辨认的毛病是方法本身复杂••。虽然神经网络以及在盘算机科学中对其的利用已经有了好几十年,建立一个好的神经网络对于大多数程序员来说还是有一些艰苦的••。大多数开发者可能对数据结构中的图和树比较熟悉,而对神经网络中标准和含混逻辑的实现可能一点都不懂得••。这种缺乏建立神经网络的经验是一个宏大的艰苦,即使能够成功的构建一个神经网络,程序的调试相当艰苦••。

和基于算法的方法相比,神经网络依附大批的参数来能得到准确的成果••。参数的个数随着神经元的个数增长••。每一个神经元可以用来辨认多个手势,每一个神经远的参数的变更都会影响其他节点的辨认成果••。配置和调剂这些参数是一项艺术,需要经验,并没有特定的规矩可循••。然而,当神经网络配对机器学习过程中手动调剂参数,随着时间的推移,系统的辨认精度会随之进步••。

4.3 基于样本的辨认

基于样本或者基于模版的手势辨认系统能够将人的手势和已知的手势相匹配••。用户的手势在模板库中已经规范化了,使得能够用来盘算手势的匹配精度••。有两种样本辨认方法,一种是存储一系列的点,另一种方法是应用类似的Kinect SDK中的骨骼追踪系统••。在后面的那个方法中,系统中包含一系列骨骼数据和景深帧数据,能够应用统计方法对产生的影像帧数据进行匹配以辨认出已知的帧数据来••。

这种手势辨认方法高度依附于机器学习••。辨认引擎会记载,处理,和重用当前帧数据,所以随着时间的推移,手势辨认精度会逐步进步••。系统能够更好的辨认出你想要表达的具体手势••。这种方法能够比较容易的辨认出新的手势,而且较其他两种方法能够更好的处理比较复杂的手势••。但是建立这样一个系统也不容易••。首先,系统依附于大批的样本数据••。数据越多,辨认精度越高••。所以系统需要大批的存储资源和CPU时间的来进行查找和匹配••。其次系统需要不同高度,不同胖瘦,不同穿着(穿着会影响景深数据提取身材轮廓)的样本来进行某一个手势••。

5.辨认常见的手势

选择手势辨认的方法通常是依附于项目标需要••。如果项目只需要辨认几个简略的手势,那么应用基于算法或者基于神经网络的手势辨认就足够了••。对于其他类型的项目,如果有兴趣的话可以投入时间来建立可复用的手势辨认引擎,或者应用一些人家已经写好的辨认算法,接下来本文介绍几种常用的手势,并演示如何应用算法的方法来辨认他们,手势辨认的另外两种方法由于其复杂性本文不做介绍••。

不论选择哪种手势辨认的方法,都必须考虑手势的变更领域••。系统必须具有机动性,并容许某一个手势有某个领域内的变动••。很少有人能够每次都做一模一样的手势••。例如,考虑周伯通当前左右手画圆圈这个手势,重复这一手势10次,圆形的中心每次都在一个点吗,圆形的起点和重点每次都在雷同的处所吗?每次画圆的时长都一样吗?然后应用右手做这个动作,最后比较成果••。或者拉几个朋友或者家人来做,然后视察••。也可以站在镜子前面看自己做,或者应用录像设备录下来再看••。技巧就是对于某一手势,让尽可能多的人来做,然后试图标准化这一手势••。手势辨认一个比较好的方法就是关注手势最核心的部分而不是哪些外在的细枝末节••。

5.1 挥动(wave)手势

只要玩过Xbox上的体感游戏,可能都应用过挥手这个手势••。挥手这一手势不论年纪大小都能够做的一个简略动作••。这是一个友爱的,快活的手势,人们通常挥手或者招手来打招呼或者道别••。在利用开发的高低文中,挥手手势通常告诉利用程序已经筹备好了,可以开端体验利用了••。

挥手是最简略最基础的手势••。应用算法方法能够很容易辨认这一手势,但是之前讲到的任何方法也能够应用••。虽然挥手是一个很简略的手势,但是如何应用代码来辨认这一手势呢?读者可以在镜子前做向自己挥手,然后仔细视察手的运动,尤其注意视察手和胳膊之间的关系••。持续视察手和胳膊之间的关系,然后视察在做这个手势事身材的全部姿势••。有些人保持身材和胳膊的不动,应用手段左右移动来挥手••。有些人保持身材和胳膊不动应用手段前后移动来挥手••。可以通过视察这些姿势来懂得其他各种不同挥手的方法••。

XBOX中的挥手动作定义为:从胳膊开端到肘部弯曲••。用户以胳膊肘为焦点来回移动前臂,移动平面和肩部在一个平面上,并且胳膊和地面保持平行,在手势的中部(下图1),前臂垂直于后臂和地面••。下图展现了这一姿势••。

 

 

从图中可以视察得出一些规律,第一个规律就是,手和手段都是在肘部和肩部之上的,这也是大多是挥手动作的特点••。这也是我们辨认挥手这一手势的第一个标准••。

第一幅图展现了挥手这一姿势的中间地位,前臂和后臂垂直••。如果用户手臂转变了这种关系,前臂在垂直线左边或者右边,我们则认为这是该手势的一个片断••。对于挥手这一姿势,每一个姿势片断必须来回重复多次,否则就不是一个完整的手势••。这一运动规律就是我们的第二个准则:当某一手势是挥手时,手或者手段,必须在中间姿势的左右来回重复特定的次数••。应用这两点通过视察得到的规律,我们可以通过算法建立算法准则,来辨认挥动手势了••。

算法通过盘算手离开中间姿势区域的次数••。中间区域是一个以胳膊肘为原点并给予必定阈值的区域••。算法也需要用户在必定的时间段内完成这个手势,否则辨认就会失败••。这里定义的挥动手势辨认算法只是一个单独的算法,不包含在一个多层的手势辨认系统内••。算法掩护自身的状态,并在辨认完成时以事件情势告诉用户辨认成果••。挥动辨认监督多个用户以及两双手的挥动手势••。辨认算法盘算新产生的每一帧骨骼数据,因此必须记载这些辨认的状态••。

下面的代码展现了记载手势辨认状态的两个枚举和一个结构••。第一个名为WavePosition的枚举用来定义手在挥手这一动作中的不同地位••。手势辨认类应用WaveGestureState枚举来追踪每一个用户的手的状态••。WaveGestureTracker结构用来保存手势辨认中所需要的数据••。他有一个Reset方法,当用户的手达不到挥手这一手势的基础动作条件时,比如当手在胳膊肘以下时,可调用Reset方法来重置手势辨认中所用到的数据••。

private enum WavePosition{
    None = 0,
    Left = 1,
    Right = 2,
    Neutral = 3
}private enum WaveGestureState{
    None = 0,
    Success = 1,
    Failure = 2,
    InProgress = 3
}private struct WaveGestureTracker{    public int IterationCount;    public WaveGestureState State;    public long Timestamp;    public WavePosition StartPosition;    public WavePosition CurrentPosition;    public void Reset()
    {
        IterationCount = 0;
        State = WaveGestureState.None;
        Timestamp = 0;
        StartPosition = WavePosition.None;
        CurrentPosition = WavePosition.None;
    }
}

下面代码显示了手势辨认类的最基础结构:它定义了五个常量:中间区域阈值,手势动作持续时间,手势离开中间区域左右移动次数,以及左手和右手标识常量••。这些常量应当作为配置文件的配置项存储,在这里为了简便,所以以常量声明••。WaveGestureTracker数组保存每一个可能的游戏者的双手的手势的辨认成果••。当挥手这一手势探测到了之后,触发GestureDetected事件••。

当主程序吸收到一个新的数据帧时,就调用WaveGesture的Update方法••。该方法循环遍历每一个用户的骨骼数据帧,然后调用TrackWave方法对左右手进行挥手姿势辨认••。当骨骼数据不在追踪状态时,重置手势辨认状态••。

public class WaveGesture{    private const float WAVE_THRESHOLD = 0.1f;    private const int WAVE_MOVEMENT_TIMEOUT = 5000;    private const int LEFT_HAND = 0;    private const int RIGHT_HAND = 1;    private const int REQUIRED_ITERATIONS = 4;    private WaveGestureTracker[,] _PlayerWaveTracker = new WaveGestureTracker[6, 2];    public event EventHandler GestureDetected;    public void Update(Skeleton[] skeletons, long frameTimestamp)
    {        if (skeletons != null)
        {            Skeleton skeleton;            for (int i = 0; i < skeletons.Length; i++)
            {
                skeleton = skeletons[i];                if (skeleton.TrackingState != SkeletonTrackingState.NotTracked)
                {
                    TrackWave(skeleton, true, ref this._PlayerWaveTracker[i, LEFT_HAND], frameTimestamp);
                    TrackWave(skeleton, false, ref this._PlayerWaveTracker[i, RIGHT_HAND], frameTimestamp);
                }                else                {                    this._PlayerWaveTracker[i, LEFT_HAND].Reset();                    this._PlayerWaveTracker[i, RIGHT_HAND].Reset();
                }
            }
        }
    }
}

 

下面的代码是挥手姿势辨认的重要逻辑方法TrackWave的主体部分••。它验证我们先前定义的构成挥手姿势的条件,并更新手势辨认的状态••。方法辨认左手或者右手的手势,第一个条件是验证,手和肘关节点是否处于追踪状态••。如果这两个关节点信息不可用,则重置追踪状态,否则进行下一步的验证••。

如果姿势持续时间超过阈值且还没有进入到下一步骤,在姿势追踪超时,重置追踪数据••。下一个验证手部关节点是否在肘关节点之上••。如果不是,则根据当前的追踪状态,挥手姿势辨认失败或者重置辨认条件••。如果手部关节点在Y轴上且高于肘部关节点,方法持续断定手在Y轴上相对于肘关节的地位••。调用UpdatePosition方法并传入合适的手关节点所处的地位••。更新手关节点地位之后,最后判断定义的重复次数是否满足,如果满足这些条件,挥手这一手势辨认成功,触发GetstureDetected事件••。

private void TrackWave(Skeleton skeleton, bool isLeft, ref WaveGestureTracker tracker, long timestamp)
{
    JointType handJointId = (isLeft) ? JointType.HandLeft : JointType.HandRight;
    JointType elbowJointId = (isLeft) ? JointType.ElbowLeft : JointType.ElbowRight;
    Joint hand = skeleton.Joints[handJointId];
    Joint elbow = skeleton.Joints[elbowJointId];    if (hand.TrackingState != JointTrackingState.NotTracked && elbow.TrackingState != JointTrackingState.NotTracked)
    {        if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp)
        {
            tracker.UpdateState(WaveGestureState.Failure, timestamp);
            System.Diagnostics.Debug.WriteLine("Fail!");
        }        else if (hand.Position.Y > elbow.Position.Y)
        {            //应用 (0, 0) 作为屏幕的中心.  从用户的视角看, X轴左负右正.            if (hand.Position.X <= elbow.Position.X - WAVE_THRESHOLD)
            {
                tracker.UpdatePosition(WavePosition.Left, timestamp);
            }            else if (hand.Position.X >= elbow.Position.X + WAVE_THRESHOLD)
            {
                tracker.UpdatePosition(WavePosition.Right, timestamp);
            }            else            {
                tracker.UpdatePosition(WavePosition.Neutral, timestamp);
            }            if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS)
            {
                tracker.UpdateState(WaveGestureState.Success, timestamp);
                System.Diagnostics.Debug.WriteLine("Success!");                if (GestureDetected != null)
                {
                    GestureDetected(this, new EventArgs());
                }
            }
        }        else        {            if (tracker.State == WaveGestureState.InProgress)
            {
                tracker.UpdateState(WaveGestureState.Failure, timestamp);
                System.Diagnostics.Debug.WriteLine("Fail!");
            }            else            {
                tracker.Reset();
            }
        }
    }    else    {
        tracker.Reset();
    }
}

 

下面的代码添加到WaveGestureTracker结构中:这些赞助方法掩护结构中的字段,使得TrackWave方法易读••。唯一需要注意的是UpdatePosition方法••。TrackWave调用该方法断定手的地位已经移动••。他的最重要目标是更新CurrentPosition和Timestamp属性,该方法也负责更新InterationCount字段合InPorgress状态••。

public void UpdateState(WaveGestureState state, long timestamp)
{
    State = state;
    Timestamp = timestamp;
}public void Reset()
{
    IterationCount = 0;
    State = WaveGestureState.None;
    Timestamp = 0;
    StartPosition = WavePosition.None;
    CurrentPosition = WavePosition.None;
}public void UpdatePosition(WavePosition position, long timestamp)
{    if (CurrentPosition != position)
    {        if (position == WavePosition.Left || position == WavePosition.Right)
        {            if (State != WaveGestureState.InProgress)
            {
                State = WaveGestureState.InProgress;
                IterationCount = 0;
                StartPosition = position;
            }

            IterationCount++;
        }

        CurrentPosition = position;
        Timestamp = timestamp;
    }
}

上述代码片断就可以实现挥动(wave)手势辨认的逻辑了••。

6. 结语

本文重要介绍了手势辨认中设计的基础概念以及手势辨认的发展过程,在此基础上介绍了手势辨认的三种基础方法:基于算法的手势辨认¶••⊿基于神经网络的手势辨认和基于样本库的手势辨认••。

 

深圳市劲锐科技有限公司专注于手势触摸ic,手势触控ic,手势触摸芯片,手势触控芯片,手势触摸按键方案开发设计多年,能满各种客户的个性需求••。

 

 

深圳劲锐佳科技有限公司 版权所有
接洽电话:0755-83088967 83088481
九亿九彩票平台 75秒赛车玩法规则 75秒赛车投注官网 秒速时时彩如何购买 SG飞艇投注平台 qq分分彩开奖结果 75秒赛车开奖结果 幸运飞艇登入平台 辽宁福彩网首页 快速飞艇官网开奖