简单教程 如何用Kinect&Unity实现特定动作识别

Xsens动作捕捉 2022-11-26 13233

简单教程  如何用Kinect&Unity实现特定动作识别  第1张
Kinect骨骼识别

Kinect体感识别设备有一项最重要也是最基础的应用就是:识别特定动作。今天我们就在Windows系统利用KinectStudio、VisualGestureBuilder和Unity3d来实现特定动作的识别。


首先我们了解一下Kinect骨骼识别的原理:

Kinect骨骼图是由深度图得到的:KinectV2通过自己的红外发射器投射经调制的近红外光线,照射到物体之后发生反射,红外相机再接受反射光线,采用TOF技术测量深度,计算光的时间差。从而计算出物体的深度(距kinect的距离)。


简单教程  如何用Kinect&Unity实现特定动作识别  第2张
Kinect深度图和骨骼识别

然后将这个侦测到的3d深度图像转换到骨架追踪系统,该系统最多可以追踪6个人。Kinect采用分隔策略将人体从复杂的背景中区分开来在这个阶段,为每个人在深度图像中创建分割遮罩(有点儿像opencv里面识别轮廓),将人物同背景分割开来。

再然后,Kinect会寻找出可能是人的物体,毕竟Kinect所具备的感官只有“视觉”和“听觉”,它不能判定你是否具有智慧、是否具有生物特征。它只能通过自己的“眼睛”去看,只要相似度达到判定阈值,它就会判定眼前的东西为人。你可以试试用衣架挂一件衣服,Kinect也不会拒绝的)。


下面我们来开始本期的教学环节:

一、首先,打开Kinect Studio,转到Record界面。连接好你的Kinect。如果连接失败请打开“服务”,手动开启Kinect Monitor服务。

简单教程  如何用Kinect&Unity实现特定动作识别  第3张
KinectStudio界面

KinectStudio界面


二、调整Kinect的位置便于我们录制自己/朋友的动作,点击左上方红色圆点按钮开始录制。然后进入Kinect的识别范围间断性地重复某一动作。比如笔者录制了一个向上拍手的动作:

简单教程  如何用Kinect&Unity实现特定动作识别  第4张
录制动作

点击结束录制,Kinect Studio会贴心地为我们自动保存这个录像片段。具体的保存位置你可以在FILE页找到。

多次重复是为了令样本的数量多一些,你也可以在间隔内稍微变换位置或者微微屈膝,让训练样本更多样化一些。


三、同Cortana小娜联系一下感情,在Cortana搜索页键入:“Visual Gesture Builder”,并打开软件,单击“File--New Solution”新建一个项目,自行命名,我的叫做DemoClap:

简单教程  如何用Kinect&Unity实现特定动作识别  第5张
VGB界面

右键你刚刚创建的工程,我这里是上图中被选中的DemoClap,选择Create New Project With Wizard,出现VGB Gesture Wizard的界面,点击Next:

简单教程  如何用Kinect&Unity实现特定动作识别  第6张
VGB创建引导页1

给我们刚才记录的动作命名,我的叫DemoClap:

简单教程  如何用Kinect&Unity实现特定动作识别  第7张
VGB创建引导页2

这里是询问我们的动作是否包含下半身的动作,这里我选择No:

简单教程  如何用Kinect&Unity实现特定动作识别  第8张
VGB创建引导页3

这里是询问我们是否需要判定手部状态(张开、握紧等),这里我选择No:

简单教程  如何用Kinect&Unity实现特定动作识别  第9张
VGB创建引导页4

这里是选择需要判断的骨骼的部分,每一张都有图解,我们可以根据图解选择自己需要的类型:

简单教程  如何用Kinect&Unity实现特定动作识别  第10张
VGB创建引导页5

这里是询问我们的动作是否区分左右。如果我们选择Yes,他就会创建两个子项目:Right & Left。这里我们选择No:

简单教程  如何用Kinect&Unity实现特定动作识别  第11张
VGB创建引导页6

这个界面是询问我们的动作是离散还是连续判定:离散型会关注我们记录的动作“发生了”or“没发生”;而连续型(原文的progress:过程、发展)会关注同记录的动作的匹配程度——最终告诉你:80%相似,这样的结果。

简单教程  如何用Kinect&Unity实现特定动作识别  第12张
VGB创建引导页7

这里就是说,将会创建下面的gesture,如果你选择了左右需要被判断,那么下面会出现后缀为right 和 left的两个gesture:

简单教程  如何用Kinect&Unity实现特定动作识别  第13张
VGB创建引导页8

单击Confirm,就会生成我们的工程:

简单教程  如何用Kinect&Unity实现特定动作识别  第14张
VGB工程界面

这里一共有两个文件,其中不带后缀的就是我们训练的样本。带.a 后缀的则是测试gesture的一个文件。

然后我们利用刚才收集的视频片段,我们的样本来创建正负样本。选中DemoClap,右键选择“Add Clip”,将我们刚才录制的.xef 文件导入。你可以从Kinect Studio的文件默认保存位置找到它。

简单教程  如何用Kinect&Unity实现特定动作识别  第15张
添加录制动作片段

之后我们需要告诉训练器哪些是正样本——也就是记录了我们需要的动作的一段连续的帧;相对的,负样本就是记录了我们不需要动作的帧。

我们按住shift +鼠标左键可以选取一段连续的帧,然后在表示当前帧位置的竖线上右键就可以将一段帧标记为正样本,以这段帧上面出现蓝色线段未标志:

简单教程  如何用Kinect&Unity实现特定动作识别  第16张
标记正负样本

下面,全部选好之后,我们选中总工程文件,右键“Build”。并耐心等待。

当Output提示我们完成时,并且没有显示错误,那么我们的动作分类器已经训练完成了。

记得刚才说的.a吗,一般我们会记录很多个动作样本,然后把其中的2/3用于训练分类器,1/3用于测试这个分类器。如果你还剩下一些没有训练的视频片段,可以把视频add clip到.a 的文件之下,来测试分类器。

如果你没有额外的视频片段了,右键工程选择Live Preview,选择刚刚Build完成之后在output栏保存的.gba/.gbd分类器文件。VGB软件会打开你的Kinect并且实时判断你当前的动作。直方图内的数值越高,表示你的动作越符合。


简单教程  如何用Kinect&Unity实现特定动作识别  第17张
LiveView检测分类器


四、在Unity3d中调用分类器

(*在步骤开始之前,确保你已经完成了Kinect for Windows插件下载和安装。)
如果没有,请戳下方的链接进行相应操作:
https://developer.microsoft.com/en-us/windows/kinect
下载Tools and extensions列表下的 Unity Pro Packages
简单教程  如何用Kinect&Unity实现特定动作识别  第18张
UnityPro packages下载


我们在Unity中新建一个项目,导入kinect for Windows的Unity插件,Kinet.2.0和Kinect.VisualGestureBuilder.2.0包:


简单教程  如何用Kinect&Unity实现特定动作识别  第19张
导入Kinect for Windows插件

导入完毕之后,打开KinectView文件夹下的MainScene:

简单教程  如何用Kinect&Unity实现特定动作识别  第20张
打开MainScene
简单教程  如何用Kinect&Unity实现特定动作识别  第21张
运行MainScene

创建一个StreamingAssets文件夹,将我们在VGB中训练获得的动作文件放入:

简单教程  如何用Kinect&Unity实现特定动作识别  第22张
放入分类器模型DemoClap.gbd


新建一个空物体,命名为GestureDetector,并为它创建两个C#脚本,GestureSourceManager和GestureController:

简单教程  如何用Kinect&Unity实现特定动作识别  第23张
创建空物体,添加脚本

然后我们来编辑这两个脚本文件,在GestureSourceManager中,我们对捕捉到的每个动作进行判断,这里设置阈值为0.8,也就是说相似度超过0.8我们就判定为符合条件:

1. if (gesture.GestureType == GestureType.Discrete)  

2. {

3. DiscreteGestureResult result = null; // Provides methods for determining the status of a discrete gesture detection.

4. discreteResults.TryGetValue(gesture, out result);

5.

6. if (result.Confidence > 0.8) // Gets a value indicating the confidence level of the gesture detection.

7. {

8. // Fire Event

9. if (OnGesture != null) // public event GestureEvent OnGesture;

10. {

11. Debug.Log("Detected Gesture " + gesture.Name + " with Confidence " + result.Confidence);

12. OnGesture(this, new KinectGestureEvent(gesture.Name, result.Confidence));

13. }

14. }

15.}

再用GestureController来接收这个动作事件,在控制台输出我们的动作是否符合:

1. private void clap_Doublehand(object sender, KinectGestureEvent e)

2. {

3.

4. if (e.name.Equals("clapDoublehand"))

5. {

6. Debug.Log("clapDoublehand!!!");

7. Clap = true;

8. } else

9. {

10. Clap = false;

11. }

12. }

之后我们单击运行,进入Kinect的检测范围,测试我们的动作,当我举起双手并进行拍手时,观察到控制台输出:

简单教程  如何用Kinect&Unity实现特定动作识别  第24张
观察控制台输出

我们就成功地完成了特定动作识别。

*注意:请在插件导入的MainScene中进行操作,因为GestureSourceManager需要手动放置一个场景中的BodyManager物体到script上。


完整代码请自取


简单教程  如何用Kinect&Unity实现特定动作识别  第25张
c#文件
链接:https://pan.baidu.com/s/1oZs7E5I9gPTVyqLt_mAkzA
提取码:gwgn

The End