基于Unity3D和Kinect的低动作检测精度下的高交互反馈方法及系统与流程

文档序号:18462933发布日期:2019-08-17 02:11阅读:621来源:国知局
基于Unity3D和Kinect的低动作检测精度下的高交互反馈方法及系统与流程

本发明属于人机交互领域,具体涉及一种基于unity3d和kinect的低动作检测精度下的高交互反馈方法。



背景技术:

kinect的推出让摄像头不仅能接收平面图像信息,而且能通过红外设备获取图像的深度信息,使得摄像头所获得的数据从二维数据变为三维数据。在此基础上kinect提取出了含有三维坐标信息的骨骼数据,使得对人体关节点的位置捕捉成为可能,用户可以直接通过肢体动作完成人机交互。

现有技术在人机交互的姿势识别部分,多为针对骨骼数据或关节节点的大规模匹配算法,如《基于kinect角度测量的姿势识别算法》、《基于kinect的人体姿势识别算法与实现》等。具体如《基于kinect的动作评价方法研究》中,通过特征向量对样本集进行训练,并使用knn(k-nearestneighbor,最邻近)算法作为分类器对姿势进行识别。在动作评价中,分析了运动特征序列的时间特性以后,采用线性回归的方法对样本曲线进行训练,使用最小二乘法拟合出一条最佳角度曲线作为标准模板,再考虑到曲线之间时间序列长短不一的问题,通过dtw(dynamictimewarping,动态时间归整)算法对不同长度的关节角度曲线进行匹配,并且通过定义一套公式对动作进行评价,然后以曲线之间dtw差值作为实验参数,最终确定识别姿势。这种方法主要识别的是人体的动作特征,针对人体行为动作的原始特征向量进行筛选,通过算法剔除冗余的部分,从而达到对特定姿势识别的效果。

这种方法的优点是由复合算法和大量样本带来的识别精度。但每个人的体型都不一样,身体灵活性和协调性也存在着各种差异,使得交互反馈质量不高,或通过在姿势库中重新录入样本提高交互反馈质量,但这样势必会增加需要调整姿势和新录入姿势的工作量;其次该方法使用了大量复杂算法,对于项目开发来说在使用和实现上都存在一定难度。

当存在一些需要实现简单姿势交互的项目来说,花费大量时间和精力去进行姿势库的录入和算法的调整无疑是不合适的。于此同时,这些需要简单交互的场景一般也不会要求用户做出过于标准的姿势,它们更多的是需要确定用户“试图做出该动作”的这一状态,尤其是在交互界面没有显示人体模型投射的时候,这种需求显得更加重要。



技术实现要素:

为了解决现有的人机交互的姿势识别算法复杂、工作量大及交互反馈质量不高等问题,本发明提供一种基于unity3d和kinect的低动作检测精度下的高交互反馈方法,利用unity3d引擎自身的一些特点,通过在姿势识别和交互检测两方面降低动作检测的精准性,简化交互算法,来提高体感动作交互时的反馈质量。

本发明的技术解决方案是提供一种基于unity3d和kinect的低动作检测精度下的高交互反馈方法,包括以下步骤:

s1、构建父子物体系统;

s11、在kinect中获取各关节节点空间坐标,并将获取的各关节节点空间坐标发送至unity3d,在unity3d中选取用于姿势检测的关键关节节点,所述关键关节节点与待确认关节节点之间的位置关系相对固定;

s12、根据待确认关节节点空间坐标,围绕关键关节节点,制作多组判定区,使得待确认关节节点动作时,能够落入判定区内;利用unity3d引擎给每组判定区添加判定框;

s13、然后将多组判定区绑定为该关键关节节点的子物体;将每个关键关节节点下的所有判定区称为该关键关节节点的判定组,并赋予统一前缀;

s2、在unity3d系统中录入设定姿势状态对应的姿势状态字符串,作为预设的姿势字符串;

s3、当待确认关节节点动作时,判定组检测代表待确认关节节点的碰撞事件,获得用户当前姿势;

s31、依赖unity3d的碰撞检测系统判断待确认关节节点是否在制作的判定组内,获得代表该判定组当前被触碰状态的姿势状态字符串;

s32、将代表该判定组当前被触碰状态的姿势状态字符串与预设的姿势字符串对比,若相同,获得用户当前姿势。

进一步地,步骤s31具体为:

s311、读取判定组内的第一个判定区;

s312、检查第一个判定区,确认该判定区待确认关节节点触碰的状态,获取表示该状态的单字符状态值;

s313、将获取到的单字符状态值写入代表该判定组当前姿势数据的字符串末尾;

s314、判断是否已经检查完该判定组内所有的判定区,若是,则进入步骤s32;若否,则返回步骤s311,读取下一个判定区,直至检查完所有的判定区。

进一步地,步骤s312具体为:

s3121、声明与各个待确认关节节点对应的布尔值;

s3122、获取待确认关节节点与对应判定区的位置,依赖unity3d的碰撞检测系统分别确定代表各待确认关节节点是否在此判定区内,若是,将待确认关节节点对应的布尔值修改为true,否则保留为false;

s3123、然后依据待确认关节节点对应的布尔值来确定代表该判定区当前被触碰状态的单字符状态值state。

进一步地,每个关键关节节点的判定组包括位于该关键关节节点上下、左右、前后方向的六个或六个以上的判定区。

进一步地,通过脚本控制,使每个判定组只检测待确认关节节点的碰撞事件。

进一步地,需要进行动态的姿势检测时,在步骤s13中定义一个最小速度;

在碰撞事件发生时检测发生碰撞的两者的相对速度,如果小于最小速度则判定为未发生碰撞。

进一步地,上述步骤s2具体为:

s21、针对每个判定区,通过绘制设定姿势与判定区的简易三视图来确定各判定区在该姿势下的触碰状态,并为每一种触碰状态定义一个字符;

s22、在一个设定姿势状态下,按固定顺序将当前每个判定区的触碰状态字符组合在一起得到当前状态下的姿势状态字符串。

本发明还提供一种基于unity3d和kinect的低动作检测精度下的高交互反馈系统,其特殊之处在于,包括处理器及存储器,存储器中存储计算机程序,计算机程序在处理器中运行时实现上述方法。

本发明的有益效果是:

1、本发明利用unity3d自身的碰撞检测系统,在用于姿势检测的关键关节节点周围设置多个判定区,然后将设置的判定区与该关节相对固定的节点绑定,如手部节点判定区的相对参照物为头,脚部节点判定区的相对参照物为脊椎末端;且利用unity制作判定区来构建判定组的过程较快,以string储存姿势数据,只需要知道这个姿势大致的形状和各判定组的状态定义,就可以正确地录入针对当前判定组代表该姿势的字符串值,省去了传统姿势检测中录入姿势的过程,方便姿势的输入和对比。

2、本发明每个判定组只检测自己对应的关节点碰撞,在防止误触的同时还方便将局部的姿势判定(如上半身和下半身)从全身判定中拆分出来进行局部姿势的判定。

3、本发明在unity3d中可以根据需求,自行设置关键关节节点及相对应的判定区级判定组,便于通过自定义判定组来精确化姿势检测和扩展添加新的判定组(如肘或膝盖)。

4、预测用户的交互心理,将每个响应区的敏感度单独调整,使得用户在做出交互行为时能更好地得到想象中的反馈,同时可以限制一部分识别误差导致的误操作。

附图说明

图1为upper判定组,检测lefthand和righthand的针对上半身的检测区父物体为head(头部关节节点);

图2为lower判定组,检测leftfoot和rightfoot的针对下半身的检测区父物体为spinebase(脊椎尾部关节节点);

图3为upper判定组中单个判定区中的检测逻辑流程;

图4为lower判定组中单个判定区中的检测逻辑流程;

图5为姿势检查部分gesturecheck主逻辑单帧流程图;

图6为分割细化后的lower判定组

图7为uml图。

具体实施方式

以下结合附图及具体实施例对本发明做进一步地描述。

unity3d引擎中每一个场景中的物体都称为一个gameobject,无论这个物体是否会被引擎渲染而显示在场景中,空gameobject可以利用unity3d引擎的特性构成独特的继承关系,以下对unity3d的一些特性进行详述。

monobehevior类是unity3d引擎常用的一个父类,继承了monobehevior的类能作为一个组件附加于场景中的gameobject对象(如图1-2所示),此时类中所有公共变量会显示在该gameobject对象的inspector面板中,可以由此直接输入参数。monobehevior类提供了一些与unity3d引擎自身的生命周期相关的方法,如update方法在程序运行时每帧被调用一次,ontriggerenter方法在触碰其他物体的判定区域时调用一次,ontriggerexit方法在离开其他物体的判定区域时调用一次,继承monobehevior的类通过重写这些方法可以实现一些与unity3d引擎生命周期相关联的算法,如每帧获取gameobject对象在场景中的坐标。

unity3d拥有独特的父子物体系统,在hierarchy面板中将一个gameobject对象拖动到另外一个gameobject对象下,这两个gameobject对象就成为了父子物体,前者作为后者的子物体,而后者作为前者的父物体。父物体移动旋转缩放的时候,子物体跟着移动旋转缩放。但是子物体进行移动旋转缩放的时候,父物体不跟着移动旋转缩放。子物体的移动旋转缩放数值都是相对于父物体的。举个例子来说,若子物体的坐标为(0,0,0),那么子物体就是位于父物体的原点,这个数值不因父物体的坐标变化而变化。

unity3d引擎通过给gameobject对象添加刚体和判定框可以实现一些碰撞状态的检测并获取碰撞信息。

本发明利用unity3d的父子物体系统,从kinect中获取各关节节点空间坐标,即使存在体型差的情况下,也可以找到与待确认关节节点位置相对固定的另一个关键关节节点(如头部节点对于双手的关节节点),将关键关节节点作为unity3d中的gameobject对象,围绕关键关节节点设置作为判定区的gameobject对象并添加判定框,然后将判定区部分绑定为该关键关节节点的子物体。将每个关键关节节点下的所有判定区称为判定组,并赋予统一前缀,如头部节点head下的所有子物体称为upper判定组,脊椎尾部关节节点下的所有子物体称为lower判定组。

以抬举手臂这一姿势为例,对于体型差异较大的人,将手臂平举时,手臂与头部的高度相近,由于upper判定组为头部关节节点的子物体,只需要确保upper判定组内水平区的判定框对于头部的高度在一个相对稳定的范围内,当手部抬起时,upper判定组能检测到代表手部关节节点的lefthand和righthand的碰撞事件。

如图1所示,前左右的三个判定区对应方向边界与头部关节节点的水平距离设为0.5m,上判定区对应方向边界与头部关节节点的垂直距离设为0.5m,判定区的大小设置为0.6m*1m*1m的立方体,就能相对准确地检测到手部关节节点在该方向上的挥动,同时在双手自然下垂以及在腰部高度移动时不会触发碰撞事件。

lower判定组同理,如图2所示,前后左右的四个判定区对应方向边界与脊椎尾部关节节点的水平距离设为0.3m,垂直距离设为-0.5m,判定区的大小设置为0.6m*0.6m*0.6m的正方体,就能相对准确地检测到脚部关节节点的踏步动作,同时在自然站立时不会触发碰撞事件。

通过脚本控制,使upper判定组只检测lefthand和righthand的碰撞事件,lower判定组只检测leftfoot和rightfoot的碰撞事件,避免因降低检测精度而扩大的判定框导致的误触。

结合3,对整个手部关节节点姿势判定的过程进行详细描述。

此流程图展示handtriggercheck类在upper判定组中单个判定区中的检测逻辑流程。

首先,在handtriggercheck类中声明两个布尔值islefthandin和isrighthandin来代表左手和右手是否在此判定区内;

其次,获取对应判定区和手部关节节点的位置;

然后,依赖unity3d的碰撞检测系统分别确定代表左手和右手的gameobject是否在此判定区内,即该判定区是否正在被触碰,若是,将对应的布尔值修改为true,否则保留为false。

最后,依据islefthandin和isrighthandin的值来确定并记录代表该判定区当前被触碰状态的单字符状态值state,“1”、“2”、“3”、“4”分别代表该判定区“没有被手触碰”、“被左手触碰”、“被右手触碰”、“同时被双手触碰”。

结合图4,对整个脚部关节节点姿势判定的过程进行详细描述。

此流程图展示feettriggercheck类在lower判定组中单个判定区中的检测逻辑流程。

首先,在feettriggercheck类中声明两个布尔值isleftfootin和isrightfootin来代表左脚和右脚是否在此判定区内;

然后,依赖unity3d的碰撞检测系统分别确定代表左脚和右脚的gameobject是否在此判定区内,即该判定区是否正在被触碰,若是,将对应的布尔值修改为true,否则保留为false。

最后,依据isleftfootin和isrightfootin的值来确定代表该判定区当前被触碰状态的单字符状态值state,“1”、“2”、“3”、“4”分别代表该判定区“没有被脚部触碰”、“被左脚触碰”、“被右脚触碰”、“同时被双脚触碰”。

state的定义可能每个判定组不一样,但是同判定组的所有判定区需要使用统一的state定义,在uml图中,这一步体现为使用枚举来表示统一的状态定义,最后将对应的枚举值转换为单字符赋与state。

该过程依赖于重写后的update方法,每帧会执行一次,即每帧都会更新该判定区的被触碰状态。

结合图5,说明如何获得各判定组的状态量并与预设姿势做比较,获得用户当前姿势。gesturecheck类通过公共变量bodytriggerlist获取场景中各判定组中各判定区上附加的bodytriggercheckabstract类,遍历它们获取每一个判定区代表当前被触碰状态的单字符状态值state,依次将其拼接为一个代表当前姿势状态的字符串gesturenow,bodytriggerlist遍历完成后,将gesturenow与预设的姿势字符串对比,该值可以从unity3d编辑器中直接设置,若两者相同,就认为用户做出了预设的姿势。预设的姿势字符串的设置过程如下:首先,针对每个判定区,通过绘制设定姿势与判定区的简易三视图来确定各判定区在该姿势下的触碰状态,并为每一种触碰状态定义一个字符;其次,在一个设定姿势状态下,按固定顺序将当前每个判定区的触碰状态字符组合在一起得到当前状态下的姿势状态字符串。

从图5中可以看出:

首先,依据判定组中单个判定区中的检测逻辑流程,读取第一个判定区;

然后,检查判定区,确认该判定区与待确认关节节点触碰状态,获取表示该状态的单字符返回值;

然后,将获取到的单字符返回值写入代表当前姿势数据的字符串末尾;

最后,判断是否已经检查完所有的判定区,若是,则将当前姿势数据与预设姿势数据对比,确认两者是否相同;若否则继续读取检查下一个判定区,直至完成所有的判定区。

该方式的优点是可以方便地通过string数据来定义姿势,只需要知道这个姿势大致的形状和各判定组的状态定义,就可以正确地录入针对当前判定组代表该姿势的字符串值,省去了传统姿势检测中录入姿势的过程。若遇到需要更精细的判定关键关节节点的情况,只需要将该关节节点对应的判定组中的判定区分割后细化,增加新的判定区,并重新摆放判定区的位置使其适合人类的正常肢体运动范围(如图6所示)。若需要检测其他关键关节节点以增加姿势的丰富度,则需要添加针对于该关节节点进行检测的判定组。

该过程依赖于重写后的update方法,每帧会执行一次,即每帧都会更新用户的姿势状态。

需要进行动态的姿势检测时,该方式还可以针对每个判定区对于碰撞速度的敏感度单独调整,在gesturecheck类中定义一个最小速度,在碰撞事件发生时检测发生碰撞的两者的相对速度,如果小于最小速度则判定为未发生碰撞,在检测如出拳等动态动作姿势时可以避免因判定区较大产生的手部摇晃误触,使得用户在做出交互行为时能更好地得到想象中的反馈。

图7为uml图,bodytriggercheckabstract类是一个抽象类,主要目的是声明getcollisionstate方法,子类通过重写该方法来传递自身所定义的关节节点碰撞状态;handtriggercheck类继承bodytriggercheckabstract,附加在upper判定组的各个判定区上,通过重写ontriggerenter方法获取被碰撞方的gameobject对象信息来确定自己是否被lefthand或righthand触碰,通过实现getcollisionstate方法来使私有枚举定义的单字符状态值state变得对其他类型可读。feettriggercheck类与handtriggercheck类似,附加在lower判定组上的各个判定区上,通过重写ontriggerenter方法获取被碰撞方的gameobject对象信息来确定自己是否被leftfoot或rightfoot触碰,通过实现getcollisionstate方法来使私有枚举定义的单字符状态值state变得对其他类型可读。gesturecheck类是核心功能类,它通过公共变量bodygesturelist获取场景中存在的所有继承自bodytriggercheckabstract的类,从而获取两个判定组的数据。重写update方法,从upper判定组和lower判定组获取它们每帧的状态信息,并拼接成一个代表当前姿势的字符串值,将这个值与bodygesturelist中预设的代表各姿势的字符串值顺次做比较,若两者相等,则认为用户在当前帧处于该姿势中。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1