这一篇,则是来介绍一下,怎样透过 OpenNI,把 Kinect 抓到的人体骨架动作,转换为一般的键盘输入。这边用的,是美国 USC(University of Southern California、南加州大学)创新科技研究所(Institute for Creative Technologies、网页) 的 MxR Lab 所开发的 FAAST(Flexible Action and Articulated Skeleton Toolkit,官方网页)。
他们最有名的宣传影片,应该就是用这套 FAAST 来玩《魔兽世界》(WOW、World of Warcraft )了!(参考)
下面就是官方放在 YouTube 的展示影片:
说实话啦,Heresy 自己看完只会觉得:「玩这游戏还真累啊…」,不过基本上,这虽然只是一般的键盘对应,但的确是个满有趣的应用。
而要怎么做到一样的事呢?基本上,第一步骤就是要先以《在 Windows 上安装 Kinect(含 MMD 使用 Kinect 简易教学)》一文中的方式,将 Kinect、OpenNI 以及 NITE 安装好,并确定可以运作。而接下来,就是到 FAAST 的官方网站,下载 FAAST 的最新版程序(目前是 0.04、直接下载)。下载之后,他会是一个 ZIP 的压缩文件,解压缩之后,会有四个档案:
在窗口的上方,有一个黑色的框,这边是会显示 OpenNI 透过 Kinect 所抓到的信息。而中间则有三个页签:「Sensor」、「Skeletion」、「Actions」可以切换,目前的版本在这里,「Skeletion」基本上是没有用的,所以会用到的只有「Sensor」和「Actions」这两页。窗口最下方则是有一个文字区域,会显示所有的讯息,可以当作他是在输出除错用的讯息。
而 FAAST 程序执行起来后不会自动联机到 Kinect,要自己去按「Sensor」这个页签里的「Connect」按钮;如果有正确连接到的话,按钮会被反白、文字也会变成是「Connected!」,同时上方的黑框也会开始显示所抓取到的信息(会类似 NITE 里的范例 Sample-StickFigure.exe)。
再来,最重要的,就是要设定动作和键盘的对应了!目前 FAAST 还只能把动作对应到键盘的事件,而没办法对应鼠标或游戏杆,这点算是比较可惜的;不过根据官方网页的说法,他们是会再继续开发的。
而如果要设定动作和键盘的对应,则是要切到「Actions」这一页(下图)。
在这边可以发现,他中间有很大的一块区域,可以输入文字,这里就是用来编辑、显示动作和键盘对应的内容的部分,这也是最重要要调整的区域了!预设开启 FAAST 应该已经有几行基本的内容了,可以当作范例来参考。另外,在官网上他们也有提供他们用来操作 WOW 的配置文件,可以让大家下载回去自己试试看(下载连结)。
而在编辑区域的下方还有三个按钮,右方的「Load File」和「Save File」是用来读取和储存对应配置文件用的;而「Start Input Emulation」就是开启输入仿真的功能,当一切就绪后,要按下这个钮,FAAST 才会真的开始分析动作,进行键盘的输入。
接下来,来看最重要的,也就是键盘对应要怎么写吧~他默认的范例内容为:
# mappings from input events to output events
# format: event_name threshold output_type event
lean_left 20 key a
lean_right 20 key d
lean_forwards 15 key w
lean_backwards 15 key s
一开始以「#」开始的两行都是批注,可以不用管他。而之后的四行,则代表了四种动作,各自对应到四个不同的按键;在这里,他就是把身体向左倾(lean_left)对应成「a」、向右倾(lean_right)对应成「d」、向前倾(lean_forwards)对应成「w」、向后倾(lean_backwards)对应成「s」。
而这边应该也可以看的出来,实际上这个设定的内容,每行是有四个元素的,他的格式是:
action_name action_threshold virtual_event_type virtual_event_name
他们的意义依次如下:
代表侦测到的动作名称,是由 FAAST 定义的;像上面的「lean_left」这类的,就是 FAAST 定义的动作名称。
代表要这个动作的判定门坎值,单位会因为不同的动作而不同;像在上面的例子里,因为定义的动作都是倾斜,所以它的单位就是角度,代表倾斜几度才算数。
代表在前面的动作发生的情况下,要送出哪一类的虚拟事件给计算机。在目前的版本,只有一般按键的「key」和特殊按键的「key_special」两种。
这一项则是在描述前一项「virtual_event_type」的细节。以「key」来说的话,就直接是单一字符了~而如果是「key_special」的话,则是要搭配十进制的 Virtual-Key Codes。
在动做方面,目前的 FAAST 分为「skeleton」(骨架)和「NITE」两部分。前者就是透过整个人体骨架的姿势来做判断,在目前的版本有 24 个动作;而后者则是 NITE 侦测出来的手势的部分,目前有七种。下方则是完整的列表:
类型 |
动作名称 |
意义 |
条件值(单位) |
skeleton |
lean_left |
身体左倾 |
身体左倾角度(度) |
lean_right |
身体右倾 |
身体右倾角度(度) |
|
lean_forwards |
身体前倾 |
身体前倾角度(度) |
|
lean_backwards |
身体后倾 |
身体后倾角度(度) |
|
left_arm_forwards |
左手前伸 |
手到肩膀的距离(英寸) |
|
left_arm_down |
左手放下 |
手到肩膀的距离(英寸) |
|
left_arm_up |
左手举起 |
手到肩膀的距离(英寸) |
|
left_arm_out |
左手向左伸 |
手到肩膀的距离(英寸) |
|
left_arm_across |
左手向右伸 |
手交错过身体到肩膀的距离(英寸) |
|
right_arm_forwards |
右手前伸 |
手到肩膀的距离(英寸) |
|
right_arm_down |
右手放下 |
手到肩膀的距离(英寸) |
|
right_arm_up |
右手举起 |
手到肩膀的距离(英寸) |
|
right_arm_out |
右手向右伸 |
手到肩膀的距离(英寸) |
|
right_arm_across |
右手向左伸 |
手交错过身体到肩膀的距离(英寸) |
|
left_foot_forwards |
左脚往前 |
脚到左臀部的距离(英吋) |
|
left_foot_sideways |
左脚往左 |
脚到左臀部的距离(英吋) |
|
left_foot_backwards |
左脚往后 |
脚到左臀部的距离(英吋) |
|
left_foot_up |
左脚举起 |
左脚离地高度(英吋) |
|
right_foot_forwards |
右脚往前 |
脚到右臀部的距离(英吋) |
|
right_foot_sideways |
右脚往右 |
脚到右臀部的距离(英吋) |
|
right_foot_backwards |
右脚往后 |
脚到右臀部的距离(英吋) |
|
right_foot_up |
右脚抬起 |
右脚离地高度(英吋) |
|
jump |
跳 |
双脚离地高度(英寸) |
|
walk |
走 |
行走时双脚离地高度(英寸) |
|
NITE |
push |
推 |
速度(英吋/秒) |
swipe_up |
往上挥 |
速度(英吋/秒) |
|
swipe_down |
往下挥 |
速度(英吋/秒) |
|
swipe_left |
往左挥 |
速度(英吋/秒) |
|
swipe_right |
往右挥 |
速度(英吋/秒) |
|
circle |
画圆 |
半径(英寸) |
|
wave |
挥手 |
无(请填 0) |
有了这些数据后,又可以把动作对应到按键了~向比如说你希望右手举高到到 20 英吋,就输入「a」的话,那就只要加上一行:right_arm_up 20 key a
这样就可以了~
另外要注意,如果是要用 skeleton 的动作的话,那要和使用 Sample-StickFigure 或 MMD 时一样,先进行标准姿势的校正、识别;也就是在确认 Kinect 有正确地抓到自己的外观时,摆出标准的校正姿势(右图),让 OpenNI 可以抓到你的骨架。如此一来,他才能根据这些骨架的资料,进行分析。
而如果是要用 NITE 的手势的话,则是要先做所谓的「focus gesture」,让系统知道手在哪里;而所谓的「focus gesture」有两种,一个是「click」(其实应该算是推,也就把手往前伸再缩回来的动作)、另一个则是「wave」(手举起左右挥动数次)。详细的说明,可以参考 NITE 的「NITE Algorithms 1.3」这份文件(位于「C: program FilesPrime SenseNITEDocumentation」目录下);不过 Heresy 自己在玩的时候,总觉得手势的部分,总觉得不是任得很好就是了。
玩了一下后,Heresy 会觉得要写出一个好的设定会满麻烦的。因为基本上,有不少的动作其实是有可能同时触发的。像是「walk」由于就是要抬脚,所以很有可能同时触发到「foot_up」的事件;同样的,把手举起、身体倾斜这类的动作,也很有可能在做其他动作的时候,同时触发到。而要避免的话,大概得把条件值都设大、让他只接受大动作了…另外,他的键盘事件触发的状况,是会去仿真键盘的「压下」和「释放」两种事件,和一般键盘在压住时会不停地重复送出键盘的事件,其实有点不一样。
整体来说呢,Heresy 是觉得这类的输入方法,并不适合用来做常态的输入,不但累,而且精准度方面也还是有些问题的;也就是说,不要期望真的可以拿来取代键盘。而在鼠标的部分,由于 FAAST目前还不支持鼠标的输入,所以无法用来玩;不然 Heresy 个人会觉得,这类的输入应该比较适合用来取代鼠标的。