VR/AR手势识别
作者:丹阳
VR/AR技术的发展给人们带来了前所未有的视觉体验与交互体验,VR/AR交互中的重要一环就是手势识别技术。对于硬件厂商下游的软件开发人员最希望的就是硬件厂商能够在SDK中集成相关的手势动作,但往往不同的应用场景所需要的手势动作多种多样,硬件厂商无法把所有的手势动作全部集成到SDK中,很多时候需要用户自己去定义相关手势动作并实现相关动作的识别。今天我们就来聊一聊最近研究手势识别技术中的一些方法和收获。
一、手势的表示方法
图1手势的表示方法
主流的手势表示方法可见图1,随着硬件的发展,诸如Kinect、Realsense、Leapmotion等一系列设备的出现,3D骨骼模型成为当今在VR/AR领域最常用的手势表示方法,相对于其方法,3D骨骼模型获取的手势数据更为精准,快速。下文也将以3D骨骼模型为基础进行手势识别技术的阐述,第二部分主要对手势识别基本现状进行介绍,第三部分重点介绍使用HMM算法进行手势识别的技术流程。
二、手势动作类型及相关识别算法
手势动作主要分为静态动作和动态动作。以下主要介绍两种类型的手势动作识别的常用算法。
1. 静态动作
静态动作识别即判断某一时刻手势所处位置、角度等相关信息是否和已有模型、模板中的某个动作一致,从而完成静态动作识别。相关算法如下。
1) 几何匹配
针对不同动作使用其坐标、角度等信息与设定的标准动作进行匹配,计算相关距离等信息进行识别。此类方法应用数学及相关几何信息,原理简单,但需针对不同动作数据需要匹配的信息进行人工处理,不够智能,可扩展性较差,对于复杂动作识别率相对较低,主要针对简单动作进行识别。
2) 机器学习类算法
K近邻(K-Nearest Neighbor Classifier):适用于简单的手势分类问题,对噪声点敏感;
朴素贝叶斯(Adaptive Naive Bayes Classifier):对于简单及复杂数据均能有效进行识别;
支持向量机(Support Vector Machine):功能强大的手势识别分类器,针对复杂手势更加有效。
2. 动态动作
动态动作即在某一时间段内获取到的连续序列,相关识别算法主要使用适合处理时间序列的算法。主流算法包括时间规整算法(DTW)和隐马尔科夫算法(HMM)。
动态时间规整算法(DTW): DTW算法基本原理来源于动态规划,在语音识别中应用较多,主要用于孤立词识别,适合处理时间系列的识别。动态动作序列也是一种时间序列上的数据,因此也可以使用该算法进行处理。
隐马尔科夫模型算法(HMM):HMM是强大的分类器,在语音识别领域应用广泛,适用于时间序列类型的样本数据。手势识别亦可使用HMM算法。HMM涉及到的相关算法:
Forward算法:(评估)给定一HMM模型,计算一观察序列O1O2...OLEN出现的概率。
Viterbi算法:(解码)给定一HMM模型,计算一观察序列O1O2...OLEN对应的最可能的隐藏序列H1H2...HLEN及该隐藏序列出现的概率。
Forward-backward(Baum-Welch)算法:(学习)给定一观察序列O1O2...OLEN,求解能够拟合这个序列的HMM模型。
三、基于HMM的动态手势动作识别
该部分主要描述基于HMM动态动作识别技术流程,未对使用到的经典算法进行过多的描述。技术流程包括:数据采集及预处理,特征提取,特征聚类,HMM模型训练,HMM动作识别。
1. 数据采集及预处理
数据采集主要用于HMM模型的训练,须保证训练样本数据的真实性、可靠性以及全面性,采集的数据包括各个骨骼点的空间位置,手指弯曲角度;
本文使用Intel Realsense采集手部的骨骼数据,采集流程如下:
图2 骨骼数据采集流程图
Step 1:获取骨骼数据流;
Step 2:判断当前处于数据采集阶段还是准备阶段,通过倒计时控制(准备阶段3s,采集阶段两秒);若非采集阶段返回step1;
Step 3:判断手势动作是否开始,未开始则返回step1(不同的手势使用不同的骨骼点作为参考骨骼点判断是否正在做出相应的手势,例如挥手动作使用手掌中心点作为参考骨骼点,点击动作使用指尖作为参考骨骼点,通过判断参考骨骼点当前帧t与t-5帧之间的空间位移,满足条件则说明手势动作开始,这一处理是为了滤除数据采集开始前及接收后的无效数据);
Step 4:一个样本序列采集结束之后,判断是否满足最小帧数要求,不满足要求,则该样本不予保存,等待下一次采集,返回step1;
Step 5:样本数据存储(手势类别标签+手势数据),开始下一样本序列的采集;
2. 特征提取
直接采集到样本数据不能直接使用,原始数据不能真实的反映手势特性,例如同一个动作,距离摄像头远近不同,启示终止位置不同,则空间位置差异巨大。为更好的表示手势数据本身的特性,须重新提取特征数据。新特征提取方法如下:
图3特征提取流程
新特征描述骨骼点各自之间的帧间差异,表征了手指与掌心之间、手指与手指之间的位置差异,记录了手指自身的弯曲角度。以上新特征有效地表征了不同手势各自的特性,可对不同手势进行有效的区分。
3. Kmeans特征聚类
由于HMM只能针对一维的输出值进行处理,而新提取的特征维度大概在30以上,所以需要对数据进行降维处理,这里使用的是Kmeans聚类算法。Kmeans聚类个数需提前指定,聚类的个数即对应HMM输出状态的个数。聚类个数越多则HMM模型对训练数据的描述更准确,但如果不能保证足够大的训练数据量则可能导致过拟合。聚类数量的选择还是要根据训练样本数据量和经验进行确定。
图4Kmeans特征聚类
Step1:归一化到0-1之间,避免不同量纲对结果的影响;
Step 2:将所有训练样本每一帧特征数据作为一个K-means聚类样本进行聚类,为避免陷入局部最优,初始中心点选取距离相对较远的点。
Step 3:计算训练样本每一帧数据到每个中心点的距离,将自身类别标签设置成距离最近的中心点的类别标签;
Step 4:重新计算每一类别的中心点;
Step 5:中心点不再改变,达到迭代次数,结束;否则继续Step3;
Step 6:保存K-mean聚类模型;
经过聚类之后,原始一个多维的时间序列样本将变成一个一维时间序列样本,即训练样本中的每一帧特征数据均被替换为分类的类别标签,方便HMM的模型训练。
4. HMM模型训练
经过以上处理,使用Baum-Welch算法对HMM模型进行训练,流程如下,方法比较经典,不在赘述。
图5 HMM模型训练过程
5. HMM动作识别
图6 HMM动作识别过程
Step 1:加载之前保存的K-means分类模型和HMM模型;
Step 2:实时更新骨骼数据buffer,并使用K-means模型进行数据降维;
Step 3:降维后的数据输入到HMM模型计算当前动作与各个手势的相似概率。若不满足最小相似概率,说明识别失败或非已知手势,返回Step 2;
Step 4:输出与当前手势相似度最大的手势类别标签及相似概率值,继续识别跳转至Step2;
四、实验结果
1.动作种类
左划、右划、上划、下划、向下点击、屏幕点击
2. 样本数据
每个动作25个训练样本,10个测试样本。训练与测试样本独立
3. 识别结果
识别正确率96%以上,识别相似概率95%以上
4. 结果分析
实验给出的手势相对简单,相应的使用几何计算也可能取得相应的识别效果,但当手势动作复杂度较大时,基于机器学习的手势识别算法优势便体现出来了,后续将继续针对复杂手势动作的识别进行研究。
五、面临问题
1. 手势库动态扩容
不同场景不同模型组合训练?成本大
所有数据训练一个模型,不同场景只对相应手势的识别概率进行考量?是否降低识别率,有待验证
2. 样本数据的可靠性和全面性
训练样本的可靠性需要保证方案中对采集到的原始数据进行了保存可回放验证动作的可靠性;HMM对训练样本需求量大,同时针对不同人群需要录制全面的数据
3. 复杂动作原始数据获取不准确
4. 聚类及输出状态值的数量
数量越大对训练数据的描述越准确,训练成本越大;
数量太大易造成过拟合,模型不够鲁邦
5. 动态识别时骨骼数据Buffer的长度
不同时刻不同人群做出同一动作所需的时间不同,对应帧数不同,Buffer定长可导致识别准确率下降。不同动作使用不同长度buffer?设置多个长度的buffer?
6. 算法性能
不同平台下实时识别时的效率,尤其是性能局限性较大的移动平台。
本文整体介绍了手势的基本类型,常用识别方法,针对动态手势动作识别,提出了一套基于HMM的技术方案并进行了相关的实验。目前复杂动态手势识别技术尚存在诸多问题,在人机交互中的应用中仍存在很多局限性,需要进行进一步研究。欢迎大家一起学习讨论。