Leap Motion概述

这是C++语言下的Leap Motion引导文章,原文地址:https://developer.leapmotion.com/documentation/Languages/C++/Guides/Leap_Overview.html,和之前一样,我使用中括号来标记自己的想法和揣测[我是译者的话]。由于本人英语水平凡凡,翻译这篇文章来锻炼英语,有能力的人最好阅读英文全文。文章由guoming.me的小明进行维护工作,欢迎指正翻译上的问题。

Leap Motion概述

Leap Motion系统可以检测并跟踪手、手指和类似手指的工具。这个器件可以在高精确度和高跟踪帧率下工作。

Leap Motion软件分析在器件可视范围内的物体。它识别手、手指和工具,可以实时获取它们的位置、手势和动作。Leap Motion的可视范围是一个倒金字塔,塔尖在设备中心。[这个很好理解,传感器一般都这样]Leap Motion的可工作范围大约在设备前方的从25到600毫米,也就是1英寸到2英尺。[2.5厘米到0.6米,果然弥补了Kinect近距离的不足啊,十分适坐在电脑前操作]

 

坐标系统

Leap Motion的系统采用了右手笛卡尔坐标系。返回的数值都是以真实世界的毫米为单位[和Kinect的深度数据一样一样的]。原点在Leap Motion 控制器的中心。x轴和z轴在器件的水平面上,x轴和设备的长边平行[z轴和短边平行,挺好记]。y轴是垂直的,以正值增加形式朝上(与朝向下的计算机图形学的坐标系相反)。距离计算机屏幕越远,z轴正值不断增加。[看到那个小绿灯吧,得确保让它朝着我们这个坐标系才对,摆放时得注意!]

上图:Leap Motion的右手坐标系统

运动追踪数据

由于Leap Motion设备最终在它视野中的手、手指和工具,它提供一组数据集更新,或者是帧,或者是数据。每帧数据包含一个基本追踪数据列表,如手、手指和工具,也包括识别出的手势和描述场景中的运动因素。

但检测到手、手指和工具或手势时,Leap Motion'软件为它分配一个唯一的ID指示符。只要这个实体一直存在于设备可视范围内,这个ID指示符就保持不变[和Kinect的骨骼追踪的ID是一致的]。如果追踪目标丢失或者失而复得,Leap Motion软件会分配一个新的ID(软件无法知道手、手指是否和之前看到的一样)[也就是说,不包含手指识别啦,和Kinect的骨骼追踪在丢失后情况完全一致]。

一个帧对象提供追踪数据、手势和在Leap Motion可视范围内的整体运动因素的列表。

追踪数据列表

Hands手---所有的手。

Pointables有端点的---手指和有段点的工具。

手指---所有的手指。

工具----所有的工具。

手势---所有手势的开始、结束或者哪个进行了更新。

这三个具有端点的列表(Pointables,Fingers,Tools)包含了任何在数据帧检测出的有端点的对象。你可以通过访问手的列表,来获取手中物体的信息。需要注意的是,如果用户的手只在Leap Motion的视野中出现一部分,那么手指或者工具都无法与手关联。[也就说,注意的手的摆放,确保手和工具同事都在可视范围内]

如果你正在通过一帧又一帧的来追踪一个单一的物体,例如手指,你可以使用与物体关联的ID,在新的帧中查询它。通过ID,你可以查询手、手指、工具、端点物体和手势。如果这个物体在当前帧存在,那么查询函数返回一个关于物体的引用。如果物体不存在了,那么返回一个特别的无效对象。无效对象被很好定义,但不包含任何有效的追踪数据。这个技术使得我们在使用Leap Motion追踪数据时,简化了大量的对于空指针的检测。

帧运动

Leap Motion软件分析总体运动,只要之前帧数据发生了位移、旋转、尺度变化等。例如,如果你把双手同时移动到Leap Motion的左侧视野,帧就包含了位移变化。如果你扭动你的双手,好像旋转一个球,帧就包含旋转。如果你将双手靠近或者远离,帧就包含缩放信息。Leap Motion软件会使用视野范围内的物体,只要分析到发生了运动。如果它只检测到一只手,那么Leap Motion程序就会基于那只手的运动,给出帧运动因素。如果它检测出一双手,它就将双手的运动趋势结合起来,给出运动因素。通过每只手对应的手对象,你也可以获取单独运动参数。

帧运动信息的产生是通过比较当前帧与之前一个特别的帧。描述合成运动的属性包含:

1.旋转坐标Rotation Axis----一个方向向量来描述坐标的旋转。

2.旋转角度Rotation Angle----相对于旋转坐标(笛卡尔坐标系)的顺时针方向的旋转角度。

3.旋转矩阵Rotation Matrix-----一个旋转的矩阵变换。

4.缩放因子Scale Factor------一个因子来描述膨胀和收缩。

5.位移Translation-----------一个向量来描述线性运动。

你可以通过运动因子来操控在你应用场景中的物体,而不必在多帧数据中跟踪单独的手和手指。[也就是factors可以手动修改]

帧结构包含一个估计某个方向上的特定运动。例如,如果缩放因子很大,难么你可以忽略在帧中的旋转、或位移(如果这可以让你的应用更实际)。通过概率方法滤去除掉不想要的运动信息可以使你的程序更容易被使用。[也就是说,只关注最主要的运动,忽视那些次要的变化,毕竟人不是机器,例如做旋转可定发生一定位移]

手模型

手模型提供关于手,或者其它被检测出来的手指、工具的坐标、特征和运动。

Leap Motion的接口函数尽可能多的提供关于一个手的信息。当时,Leap Motion程序可能无法计算出在每个帧下的手部信息。例如,当一个手攥成一个拳头,它的手指则无法被Leap Motion看到,所以手指的信息就是空。你的应用应该能处理到这些模型消失的状态。

Leap Motion程序也不判定一只手到底是左手还是右手[Kinect判断~]。在手的列表中,可以出现多余2只手的信息,因为可以不止一个人也可以出现一个类似手的物体在Leap Motion的视野范围里。但是,我们建议最多让两只手同时出现在Leap Motion控制器的视野里,这样可以确保最佳追踪质量。

手属性

手对象提供一些属性来反映一只被检测到手的物理特征。

1. 手掌坐标Palm Position-------------在Leap Motion的坐标系下,手掌中心的坐标以毫米为单位被衡量。

2.手掌速率Palm Velocity-------------手掌毫米/每秒的运动的速度。

3.手掌标准Palm Normal--------------与手掌所形成的平面的垂直向量,向量方向指向手掌内侧。

4.方向Direction-------------------由手掌中心指向手指的向量。

5.球心Sphere Center------------可以适合手掌内侧弧面的一个球心。(假设握着一个球)

6.球半径Sphere Radius------------同上,这个是球半径。当手形状变化,半径跟着变化。

方向和手掌标准是在Leap Motion坐标系下,描述手的方向的向量。

上图:手掌标准垂直于手掌往外,方向朝着手指方向。

上图:当手卷曲,球变小

球心和球半径描述了一个球,这个球满足手掌的曲率,正好可以被手掌的握着。

 

手运动

手对象还提供了一些用于描述手运动的属性。Leap Motion程序分析手的运动,包括那些与手关联的手指、工具的位移、旋转和缩放。将你的手绕着Leap Motion的运动,会产生位移。张开、扭曲和倾斜你的手,可以产生旋转。将你的手势或者工具对着Leap Motion靠近或远离,可以产生缩放。

手的运动是通过当前帧与之前特定帧对比得到的。描述手运动的属性有和Frame Motion一样。

1.旋转坐标Rotation Axis

2.旋转角度Rotation Angle

3.旋转矩阵Rotation Matrix

4.缩放因子Scale Factor

5.位移Translation

手对象同样包含了对于手运动最重要的估计。[后面一样了,不说了]

手指和工具列表

你可以通过下面三个中的一个,访问与手联系的手指和工具:

1.端点Pointables------手指和工具都是端点物体。

2.手指Fingers----------仅仅手指。

3.工具Tools-------------仅仅工具。

你还可以通过之前帧中获取的ID来访问单独的手指和工具。使用Hand::finger(),hand::tool(),或者你不需要区分手指和工具,使用Hand::pointable()函数。这些函数返回当前帧中物体的引用。如果手指和工具在此帧中,没有和手关联,那么返回一个无效的对象。

手指和工具模型

Leap Motion设备不但检测和追踪在视野范围里的手指还追踪工具。Leap Motion程序通过形状对手指类似物体进行分类。一个工具相对于手指来说是更长、更瘦还是更直。

在Leap Motion模型里,手指和工具的物理特征被抽象到一个端点对象中。手指和工具是一类端点对象,端点对象的物理特征包括:

1.长度Length-------物体的可视长度(从手长出来的部分)。

2.宽度Width-------物体的平均宽度。[注意平均哦]

3.方向Direction---一个单位朝向向量,方向与物体指向相同。(例如从底座到尖端)

4.尖坐标Tip Position----在Leap Motion坐标系下,尖的位置。

5.尖点速率Tip Velocity-----尖的运动毫米/秒。

上图:红点还是尖坐标,指针式尖方向。

Leap Motion程序把检测到的端点物体识别为手指或者是工具。使用Pointable::isTool()函数来确定是哪一类端点对象。

这个工具,比手指更长、更细和更直。

手势

Leap Motion程序把特定的运动模式识别为手势,可以猜测用户的意图或指令。Leap Motion对于一帧数据中的手势访问方法和其它的手指和手势一致的。对于每个被检测到的手势,Leap Motion都将一个手势对象Gesture object添加到帧数据中。你可以通过帧手势列表来获取手势对象。

以下是Leap Motion可以识别的运动模式。[重点来了啊,看不懂下面会有图像示意~]

1.圈Circle----一个手指头画圆。

2.挥动Swipe----手的线性运动。

3.按键点击按键Key Tap-----手指点击运动,就像按下键盘一样。

4.屏幕点击Screen Tap----对电脑屏幕方向进行垂直点击。

但Leap Motion把一个运动识别测很难过一个手势模式,它把手势对象加入帧中。如果手势重复数次,Leap Motion会把更新手势对象不断添加到随后的帧中。画圈和挥手的手势都是持续的。Leap Motion为程序在每帧中持续更新这些手势。点击时离散的手势。Leap Motion把每次点击作为独立的手势对象报告。

 

重要:在你的应用使用手势之前,你必须把每种所需要识别的手势开启。控制类有一个enableGesture()方法让你开启特定的手势识别。[也就是一开始都是关闭的,不开没法用]

画圈

Leap Motion可以识别手指在空中以圆的方式运动,返回一个圈手势Circle gesture。

上图:食指的圈手势

你可以用任何手指和工具画圈。圈手势是持续的。一旦这个手势开始,Leap Motion就会持续更新状态直到停止。但手指或者工具远离了轨迹或者运动太缓慢,圈手势则终止。

可以从CircleGesture的接口函数参考中看到更多的信息。

挥手

Leap Motion把手指的线性运动识别为挥手手势。

上图:一个水平挥手的手势。

你可以用任意手指在任意方向上作挥手手势。挥手手势是持续的。一旦手势开始,Leap Motion机会更新状态直到手势结束。当手指变换了方向或者运动太缓慢时,挥手手势结束。

更多信息可以参考SwipeGesture的接口函数文档。

点击

Leap Motion可以识别2种点击,按键点击Key Tap和向前的屏幕点击Screen Tap。

按键点击

Leap Motion把一个快速的、往下一根手指或工具的运动识别为一个按键手势Key Tap。

上图:食指的按键手势

你可以像按下钢琴键那样产生一个按键点击手势。按键点击手势时离散的。只有一个独立的手势对象会被添加到点击手势。

从KeyTapGesture接口函数可以看到更多的信息。

屏幕点击

Leap Motion可以把一个手指或者工具做一个快速的、朝前的点击识别为一个屏幕点击手势。

上图:食指的屏幕点击手势

你可以往前点击或者把手推向前方来产生一个屏幕点击,就像触摸一个与你垂直的屏幕。点击手势是离散的,只有一个独立的手势对象会被添加到点击手势。

可以在ScreenTapGesture的接口函数看到更多的信息。

你可能感兴趣的:(Leap Motion概述)