KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示

上传人:鲁** 文档编号:509505990 上传时间:2024-02-24 格式:DOC 页数:17 大小:438.50KB
返回 下载 相关 举报
KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示_第1页
第1页 / 共17页
KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示_第2页
第2页 / 共17页
KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示_第3页
第3页 / 共17页
KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示_第4页
第4页 / 共17页
KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示》由会员分享,可在线阅读,更多相关《KinectOpenNI学习笔记之6获取人体骨架并在Qt中显示(17页珍藏版)》请在金锄头文库上搜索。

1、前言MS的kinec SDK和OpenNI都提供了人体骨骼跟踪的算法,人体骨骼跟踪算法在kinect人体行为识别中非常重要,该识别过程通常被用来作为行为识别的第一步, 比如说,通过定位人体中的骨骼支架,可以提取出人手的部位,从而可以把手的部分单独拿出来分析,这样就达到了手势的定位,而后面的手势识别则可以在刚刚定 位出的领域进行处理。总而言之,一套有效的人体骨架追踪算法在kinect的一系列应用中非常有用,不过MS SDK和OpenNI虽然都提供了该算法类的直调用,但是其源码并没有开放,毕竟这是人家最核心的东东。开发环境:QtCreator2.5.1+OpenNI1.5.4.0+Qt4.8.2实

2、验说明在老版本的OpenNI中,要对人进行骨架追踪,需要人先摆出PSI的姿势,然后系统根据该姿势进行骨骼校正,待校正完成后才进行骨骼的跟踪,其流程图可以参考下面的图:由图可以看出,其完成骨骼跟踪主要分为3个部分,首先需检测到人体,然后需要固定的PSI姿势来对人体的姿势进行校正,待姿势校正完成后,才能进行人体骨骼的追踪。如果程序开发者用代码实现该过程则可以参考hersey的文章透过OpenNI / NITE 分析人体骨架(上)和透过OpenNI / NITE 分析人体骨架(下),作者在这2篇文章详细介绍了老版本的人体骨架的OpenNI实现。在新版本OpenNI1.5以后,人体骨架追踪算法更改了不

3、少,其中最大的特点就是骨架跟踪过程中少了姿势校正的那一步骤,新版本中只需要人体 站起来就可以进行跟踪了,http:/ 使用起来方便很多,程序开发也简单不少。另外人体骨骼跟踪的效果也提高了不少,一旦骨骼追踪成功后,即使人体没有保持站立姿势有 时候也还是可以继续跟踪的。新版本的人体骨骼跟踪算法使用流程图如下:下面来看看程序中的Capability,它不同于前面文章的generator:在进行骨架的判断和姿态检测是需要用到OpenNI延伸的功能,与这种延伸功能相关的类可以称作为Capability。在进行人体骨骼分析时,user generator需要有支援Skeleton和Pose Detecti

4、on这2个的capability。在程序中需要绘制骨骼节点之间的连线,而节点的坐标和法向都有函数可以获得,获得的坐标为真实世界中的坐标,画图时需要在平面上绘制,因此需要这2个坐标系的转换,转换过程用到下面的函数:XnStatus xn:DepthGenerator:ConvertRealWorldToProjective(XnUInt32 nCount, const XnPoint3D aRealWorld, XnPoint3D aProjective)该函数表示将深度图获取的真实坐标系转换成平面图形显示的投影坐标系上。第1个参数表示转换坐标点的个数,第2个参数表示真实坐标系中的坐标,第3个参

5、数表示投影坐标系下的坐标。本实验的程序分为3个类和一个主函数,其中2个类的基本部分在前面的文章中已有介绍,只需要更新其部分功能。下面是本实验中这3个类的设计。当然这都是参考heresy的博客使用Qt 显示OpenNI 的人体骨架。COpenNI类的更新:因为需要对人体进行骨骼跟踪,所以需要用到OpenNI的UserGenerator这个类。在private变量一栏增加这个类对象的声明。然后在类的Init()函数中使用Create方法产生人体的node。同上一篇博客Kinect+OpenNI学习笔记之5(使用OpenNI自带的类进行简单手势识别)中 类似,这里的人体骨架校正,跟踪等都是通过回调函

6、数的形式进行的,因此还需要在Init()函数中设置这个node的检测到有新人进入和骨骼校正完成的回 调函数(其实还有旧人体目标离去,骨骼校正开始这2个也可以设置回调函数,但在本程序中因为不需要使用它们,因此可以省略不写,http:/ 老版本的OpenNI是不 允许省略的)。另外,由于色彩节点,深度节点,以及人体检测节点都是私有变量,如果该类的对象需要获取该变量的话不方便,因此在共有函数部分分别设置了3 个共有函数来获取这3个变量。具体该类的全部代码参加本文后面的代码部分。CSkeletonItem类的设计:CSkeletonItem这个类主要来完成骨架节点位置的获取,以及画出item中节点之间

7、的连线,同时也在节点位置处画出圆圈代表对应节点的位置。在构造函数中,设计了一个二维的连接表矩阵,矩阵的大小为14*2,即有14条边,每条边有2个顶点,矩阵中对应位置的值表示的是对应边的节点骨架的标号,在OpenNI中人体的骨架节点共分为15个,手脚共12个,头部2个,躯干1个。如下图所示:程序中对这15个点编了序号,头部为0, 颈部为1, 躯干为2, 左肩膀为3, 左手肘为4, 左手腕5,右肩膀为6,右手肘为7,右手腕为8,左臀为9,左膝盖为10,左脚跟为11,右臀为12,右膝盖为13,右脚跟为14。该类中需要重写的boundingRect()函数,函数中设置了一个包含15个节点的最小矩形,因

8、为后面的绘图区域需要在这个矩形内进行,很明显,获得的这个矩形不是固定大小的,而是根据人体骨架的位置在不断变化。大小和位置同时都会发生改变。重写的paint()函数则需要完成2个部分的功能, 第一是画出骨骼中节点的位置,用圆圈显示;第二是画出2个节点之间的连线,共14条,这样通过画出的连线就可以大概看出人的位置和区域了。本文是参考的heresy文章不用校正姿势的NITE 1.5 ,heresy在设计该类的构造函数时,设计了个15*2的连接表,个人感觉设置为14*2比较合理,因为15个点刚好由14条线可以连接起来,并不是heresy所说的15条线,其实它有2条线是重合的。CKinectReader

9、类的更新:该类是在前面的文章Kinect+OpenNI学习笔记之3(获取kinect的数据并在Qt中显示的类的设计)中 对应类的更新,前面博文中的该类只是完成了深度图像和颜色图像的显示,而在本实验中,需要完成显示骨架节点之间的连线图,因此该类需要继续更新。其实现过 程主要是获取视野中人体的个数,对检测到的每个人体然后调用CSkeletonItem类中的方法UpdateSkeleton()来更新读取的节点坐 标,因为一旦坐标值发生了改变,CSkeletonItem类中的boundingRect()内容也会更改,从而其Item所在区域的矩形也会变化,最 后导致paint()函数的执行,在paint

10、()函数中完成骨骼节点连线和骨骼节点的绘图。实验结果试验效果的截图:蓝色的线表示骨骼节点之间的连线,黄色的圈表示骨骼节点。实验主要部分代码及注释(附录有实验工程code下载链接地址):copenni.cpp:#ifndef COPENNI_CLASS#define COPENNI_CLASS#include #include #include using namespace xn;using namespace std;class COpenNIpublic: COpenNI() context.Release();/释放空间 bool Initial() /初始化 status = cont

11、ext.Init(); if(CheckError(Context initial failed!) return false; context.SetGlobalMirror(true);/设置镜像 xmode.nXRes = 640; xmode.nYRes = 480; xmode.nFPS = 30; /产生颜色node status = image_generator.Create(context); if(CheckError(Create image generator error!) return false; /设置颜色图片输出模式 status = image_genera

12、tor.SetMapOutputMode(xmode); if(CheckError(SetMapOutputMdoe error!) return false; /产生深度node status = depth_generator.Create(context); if(CheckError(Create depth generator error!) return false; /设置深度图片输出模式 status = depth_generator.SetMapOutputMode(xmode); if(CheckError(SetMapOutputMdoe error!) return

13、 false; /产生手势node status = gesture_generator.Create(context); if(CheckError(Create gesture generator error!) return false; /*添加手势识别的种类*/ gesture_generator.AddGesture(Wave, NULL); gesture_generator.AddGesture(click, NULL); gesture_generator.AddGesture(RaiseHand, NULL); gesture_generator.AddGesture(MovingHand, NULL); /产生人体node status = user_generator.Create(context); if(CheckError(Create gesturen generator error!) return false; /视角校正 status = depth_generator.GetAlternativeViewPointCap().SetViewPoint(image_generator); if(CheckError(Cant set the alternative view point on depth generator!)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号