简单教程 | 如何用Kinect&Unity实现特定动作识别
Kinect体感识别设备有一项最重要也是最基础的应用就是:识别特定动作。今天我们就在Windows系统利用KinectStudio、VisualGestureBuilder和Unity3d来实现特定动作的识别。
首先我们了解一下Kinect骨骼识别的原理:
Kinect骨骼图是由深度图得到的:KinectV2通过自己的红外发射器投射经调制的近红外光线,照射到物体之后发生反射,红外相机再接受反射光线,采用TOF技术测量深度,计算光的时间差。从而计算出物体的深度(距kinect的距离)。
然后将这个侦测到的3d深度图像转换到骨架追踪系统,该系统最多可以追踪6个人。Kinect采用分隔策略将人体从复杂的背景中区分开来在这个阶段,为每个人在深度图像中创建分割遮罩(有点儿像opencv里面识别轮廓),将人物同背景分割开来。
再然后,Kinect会寻找出可能是人的物体,毕竟Kinect所具备的感官只有“视觉”和“听觉”,它不能判定你是否具有智慧、是否具有生物特征。它只能通过自己的“眼睛”去看,只要相似度达到判定阈值,它就会判定眼前的东西为人。你可以试试用衣架挂一件衣服,Kinect也不会拒绝的)。
下面我们来开始本期的教学环节:
一、首先,打开Kinect Studio,转到Record界面。连接好你的Kinect。如果连接失败请打开“服务”,手动开启Kinect Monitor服务。
KinectStudio界面
二、调整Kinect的位置便于我们录制自己/朋友的动作,点击左上方红色圆点按钮开始录制。然后进入Kinect的识别范围间断性地重复某一动作。比如笔者录制了一个向上拍手的动作:
点击结束录制,Kinect Studio会贴心地为我们自动保存这个录像片段。具体的保存位置你可以在FILE页找到。
多次重复是为了令样本的数量多一些,你也可以在间隔内稍微变换位置或者微微屈膝,让训练样本更多样化一些。
三、同Cortana小娜联系一下感情,在Cortana搜索页键入:“Visual Gesture Builder”,并打开软件,单击“File--New Solution”新建一个项目,自行命名,我的叫做DemoClap:
右键你刚刚创建的工程,我这里是上图中被选中的DemoClap,选择Create New Project With Wizard,出现VGB Gesture Wizard的界面,点击Next:
给我们刚才记录的动作命名,我的叫DemoClap:
这里是询问我们的动作是否包含下半身的动作,这里我选择No:
这里是询问我们是否需要判定手部状态(张开、握紧等),这里我选择No:
这里是选择需要判断的骨骼的部分,每一张都有图解,我们可以根据图解选择自己需要的类型:
这里是询问我们的动作是否区分左右。如果我们选择Yes,他就会创建两个子项目:Right & Left。这里我们选择No:
这个界面是询问我们的动作是离散还是连续判定:离散型会关注我们记录的动作“发生了”or“没发生”;而连续型(原文的progress:过程、发展)会关注同记录的动作的匹配程度——最终告诉你:80%相似,这样的结果。
这里就是说,将会创建下面的gesture,如果你选择了左右需要被判断,那么下面会出现后缀为right 和 left的两个gesture:
单击Confirm,就会生成我们的工程:
这里一共有两个文件,其中不带后缀的就是我们训练的样本。带.a 后缀的则是测试gesture的一个文件。
然后我们利用刚才收集的视频片段,我们的样本来创建正负样本。选中DemoClap,右键选择“Add Clip”,将我们刚才录制的.xef 文件导入。你可以从Kinect Studio的文件默认保存位置找到它。
之后我们需要告诉训练器哪些是正样本——也就是记录了我们需要的动作的一段连续的帧;相对的,负样本就是记录了我们不需要动作的帧。
我们按住shift +鼠标左键可以选取一段连续的帧,然后在表示当前帧位置的竖线上右键就可以将一段帧标记为正样本,以这段帧上面出现蓝色线段未标志:
下面,全部选好之后,我们选中总工程文件,右键“Build”。并耐心等待。
当Output提示我们完成时,并且没有显示错误,那么我们的动作分类器已经训练完成了。
记得刚才说的.a吗,一般我们会记录很多个动作样本,然后把其中的2/3用于训练分类器,1/3用于测试这个分类器。如果你还剩下一些没有训练的视频片段,可以把视频add clip到.a 的文件之下,来测试分类器。
如果你没有额外的视频片段了,右键工程选择Live Preview,选择刚刚Build完成之后在output栏保存的.gba/.gbd分类器文件。VGB软件会打开你的Kinect并且实时判断你当前的动作。直方图内的数值越高,表示你的动作越符合。
四、在Unity3d中调用分类器
(*在步骤开始之前,确保你已经完成了Kinect for Windows插件下载和安装。)
如果没有,请戳下方的链接进行相应操作:
https:// developer.microsoft.com /en-us/windows/kinect
下载Tools and extensions列表下的 Unity Pro Packages
我们在Unity中新建一个项目,导入kinect for Windows的Unity插件,Kinet.2.0和Kinect.VisualGestureBuilder.2.0包:
导入完毕之后,打开KinectView文件夹下的MainScene:
创建一个StreamingAssets文件夹,将我们在VGB中训练获得的动作文件放入:
新建一个空物体,命名为GestureDetector,并为它创建两个C#脚本,GestureSourceManager和GestureController:
然后我们来编辑这两个脚本文件,在GestureSourceManager中,我们对捕捉到的每个动作进行判断,这里设置阈值为0.8,也就是说相似度超过0.8我们就判定为符合条件:
1. if (gesture.GestureType == GestureType.Discrete)
3. DiscreteGestureResult result = null; // Provides methods for determining the status of a discrete gesture detection.
4. discreteResults.TryGetValue(gesture, out result);
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. }
再用GestureController来接收这个动作事件,在控制台输出我们的动作是否符合:
1. private void clap_Doublehand(object sender, KinectGestureEvent e)
4. if (e.name.Equals("clapDoublehand"))
5. {
6. Debug.Log("clapDoublehand!!!");