OpenNI 人体姿势识别

来源:互联网 发布:微信支付js接口文档 编辑:程序博客网 时间:2024/04/29 23:31

原址http://blog.csdn.net/mingspy/article/details/7290339

OpenNI简介

OpenNI (开放自然交互)是一个多语言,跨平台的框架,利用符合OpenNI标准的API进行编程,可以使我们与传感器和中间层的具体实现细节相脱离,同时OpenNI也允许我们获取和控制传感器层的数据。

OpenNI的中间件层是实现人体姿态的算法层,目前PrimeSense的NITE(Nature Interacte tecnoligy for End-User)提供了OpenNI标准规定的部分算法。

OpenNI使用分类器的设计概念,把传感器采集的数据逐层向上处理,产生更有用的数据。举例来说传感器采集的 原始数据---经过DepthGenerator-->产生DepthMap--经过GestureGenerator-->产生手势。

详细概念参考OpenNI文档。

程序简介

通过跟踪人的右手平移动作来控制下图中3D立方体的左右旋转。图中比较难看的小人用于显示被跟踪的人头,肩膀,肘和手的位置。程序只跟踪一个人,因为要显示多个人有点麻烦,跟踪一个更能直观的验证OpenNI各API的用法。

用法: 程序启动后,摆出Psi姿势,也就是图中小人的姿势:双手举起(缴枪投降的姿势),当图中的小人开始动时,说明已经被传感器跟踪了, 然后把右手伸出一定距离左右移动来控制立方体的左右旋转。功能比较简单,不过还是挺有意思的,有3D传感器的童鞋可以试试。

运行要求:

3D传感器(PrimeSense或Kinect)

OpenNI SDK

VS2010

代码说明

源代码在我空间里,点击下载

源代码中一个比较重要的类是UserTracker, 它封装了OpenNI的UserGenerator, 通过调用UserGenerator的SkeletonCapability的接口来跟踪人员,当有人进入传感器的可视区域后,开始寻找控制者--检测他是否摆出Psi姿势(可以换成其他的手势,不过这个调用起来比较方便。)。

[csharp] view plaincopy
  1. void userGenerator_NewUser(object sender, NewUserEventArgs e)  
  2. {  
  3.     UserInfo user = new UserInfo() { ID = e.ID };  
  4.     userDict.Add(e.ID, user);  
  5.     //userGenerator.SkeletonCapability.StartTracking(e.ID);  
  6.     if(currentUser == -1)  
  7.         poseCap.StartPoseDetection("Psi", e.ID);  
  8. }  

当检测到被跟踪者摆出Psi姿势后,强制对他的骨骼进行校准。

[csharp] view plaincopy
  1. void poseCap_PoseDetected(object sender, PoseDetectedEventArgs e)  
  2.        {  
  3.            poseCap.StopPoseDetection(e.ID);  
  4.            if (currentUser == -1)  
  5.            {  
  6.                currentUser = e.ID;  
  7.                skeletonCap.RequestCalibration(e.ID, true);  
  8.            }  
  9.        }  

校准成功后,开始跟踪该对象,并把他的骨骼位置信息发送给所有的观察者。

[csharp] view plaincopy
  1. void SkeletonCapability_CalibrationComplete(object sender, CalibrationProgressEventArgs e)  
  2.        {  
  3.            if (e.Status == CalibrationStatus.OK)  
  4.            {  
  5.                skeletonCap.StartTracking(e.ID);  
  6.            }  
  7.            else  
  8.            {  
  9.                poseCap.StartPoseDetection("Psi", e.ID);  
  10.            }  
  11.   
  12.        }  
[csharp] view plaincopy
  1. private void SkeletonThreadFunc()  
  2. {  
  3.     while (bRunning)  
  4.     {  
  5.         try  
  6.         {  
  7.             context.WaitAndUpdateAll();  
  8.         }  
  9.         catch (Exception)  
  10.         {  
  11.         }  
  12.   
  13.         int[] userIDs = userGenerator.GetUsers();  
  14.         foreach (int i in userIDs)  
  15.         {  
  16.             if (skeletonCap.IsTracking(i) && i == currentUser)  
  17.             {  
  18.                 UpdateUser(i);  
  19.             }  
  20.         }  
  21.  }  
  22. }  

主窗口的代码比较简单,就是接受UserTracker的位置信息,然后调整几个图形的位置,如果发现右手伸出一定距离,并开始左右移动,根据手的移动量进行旋转立方体。


0 0