nuihq.com qt nui ni ui kinect primesense WAVI Xtion 体感
用语约定:
- 玩家:程序开发的终端用户, 在设备前玩游戏的家伙
对玩家骨骼的追踪是Nite中的重要功能之一, 下面我就为大家简单分析以下Nite自带的 “Players” 这个例子的主要流程
简化代码
要分析代码要现精简代码, 将主要的流程提取出来, 进行分析, 例子的核心文件只有三个, main.cpp, ScreenDrawer.h, ScreenDrawer.cpp, 因为我们只是分析追踪的流程, 因此画图部分可以略去, 首先分析 main.cpp
- 首先我们要剥离的是有关画图显示的代码, 这样, 关于gl的代码我们就可以跳过
- 然后关于这个例子中有一个玩家会话控制的功能, 即玩家短暂的离开后再次回来可以让程序很快地恢复校准, 同时为上层的游戏提供一个“中间层”, 将先后加入或更换的玩家对应到游戏中的角色,会话控制的代码是写例子的人自己的实现, 也可以不看(说实话我真的没看懂), 就是 AssignPlayer , FindPlayer, LostPlayer, 这几个函数
- 接着可以略去的代码是有关深度图录像的函数, StopCapture 和 StartCapture
从入口函数入手
- 首先是从xml创建环境, 然后初始化并检查生产节点, 接着检查生产节点的能力, 这部分使用了上边定义的宏, 用来检查错误并退出main函数。
- 接着开始绑定回调函数, 将玩家事件, 校准事件绑定到对应的处理函数,
程序的流程
OpenNI 的数据获取和处理都是在他的更新函数 g_Context.WaitOneUpdateAll(g_DepthGenerator); 中进行的, 你绑定的回调函数也是在这个函数中被调用的, OpenNI有多种更新函数, 具体差别看文档~在更新函数中, OpenNI 等待并搜集所有的数据, 和之前缓存的数据一同进行处理, 如果符合某个事件的条件, 则调取你设定的回调。 这个函数一般要循环调用以持续对数据进行更新, 在官方的例子中, 他是使用opengl的显示循环进行循环调用的。接下来我们针对例子进行分析:
- 当一个玩家出现在kinect的“视野”中后, openni会对其进行识别, 如果发现这“东西”像是个人, 则调用例子中的 NewUser 函数, 例子中 NewUser 会使用 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(“Psi”, user); 函数开启这个玩家的姿势检测, 检测的姿势叫做 “Psi”, 这个姿势就是我们说的 “投降” 姿势, 双手举过头顶~
- 如果此时玩家做出了 “投降” 姿势, 则 PoseDetected 这个回调会被调用, 在这个函数中, 例子使用g_UserGenerator.GetSkeletonCap().RequestCalibration(user, TRUE); 请求对玩家进行 “校准”, 就是对其尝试进行骨骼模式匹配, 同时例子使用 g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(user); 停止玩家的姿势检测, 我实验了一下这个地方如果不停止姿势检测的话也是没有问题的, 但是如果不需要再检测玩家姿势的话就停掉吧, 毕竟可以省点资源嘛
- 之后openni会用一段时间对玩家进行骨骼模式匹配, 匹配不一定能够成功, 和玩家出现在kinect设备视野中的完整程度有关, 有过完整出现的话基本是可以顺利识别的。 当匹配完成后, 无论成功失败, 都会调用 CalibrationCompleted(xn::SkeletonCapability& skeleton, XnUserID user, XnCalibrationStatus eStatus, void* cxt) 这个函数, 我们可以看到这个函数中有对校准结果的检测, XN_CALIBRATION_STATUS_OK 代表成功, 成功的话, 例子调用了 g_UserGenerator.GetSkeletonCap().StartTracking(user) 开始对此用户进行骨骼追踪
- 至此, 就可以获取用户的骨骼数据了, 在 ScreenDrawer.cpp 中的 DrawLimb(XnUserID player, XnSkeletonJoint eJoint1, XnSkeletonJoint eJoint2) 函数中, g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(player, eJoint1, joint1), eJoint1 这个参数是从下边的DrawDepthMap函数的后边传过来的, 分别代表身体关节, 可以的值有
XN_SKEL_HEAD,
XN_SKEL_NECK,
XN_SKEL_LEFT_SHOULDER, XN_SKEL_RIGHT_SHOULDER,
XN_SKEL_LEFT_ELBOW, XN_SKEL_RIGHT_ELBOW,
XN_SKEL_LEFT_HAND, XN_SKEL_RIGHT_HAND,
XN_SKEL_TORSO,
XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_HIP,
XN_SKEL_LEFT_KNEE, XN_SKEL_RIGHT_KNEE,
XN_SKEL_LEFT_FOOT, XN_SKEL_RIGHT_FOOT
注意和改进
写到这里, 基本的流程就分析完了, 程序中有些问题
- 这里要注意一下, 由于openni是用C写的, 所以如果你要使用C++进行开发的话你的回调函数要使用静态成员函数, 或使用非成员函数, 这样的话才可以在编译时确定函数的地址, 进行绑定
- 例子程序有个缺点, 就是一个玩家校准失败后, 就不能再进行校准, 因此可以将 main.cpp CalibrationCompleted 函数修改如下
if (eStatus == XN_CALIBRATION_STATUS_OK) { ...... // 原有代码 }else { printf("请求重新校准 %d 号玩家!\n", int(user)); g_UserGenerator.GetSkeletonCap().RequestCalibration(user, false); // 重新请求校准 }
- 还有个小问题, 就是 main.cpp CalibrationEnded 这个函数是没有用的~, 下边回调中并没有绑定, 整个程序中也没有用到
相关推荐
OpenNI,全称为“Open Natural Interaction”,是一个开源的框架,主要设计用于自然用户界面(NUI)的开发,尤其在与3D传感器如Microsoft Kinect的交互中。它为开发者提供了一个标准化的接口,使得能够轻松地访问和...
3. 安装 NITE:NITE 是由 PrimeSense 提供的 OpenNI 的中间件,负责分析 Kinect 抓到的数据,转换为人体骨架、手势等数据。如果只是想要读取 Kinect 的深度信息和影像信息的话,其实可以不用安装 NITE。 4. 安装 ...
OpenNI,全称为开源自然交互(Open Source Natural Interaction),是一个为开发人员提供创建自然用户界面(NUI)的开源框架。它主要与各种传感器,如微软的Kinect,协同工作,使得开发者能够轻松地实现体感应用的...
- **Developer Kit (NITE)**:包含了各种预定义的行为,如手势识别、骨骼追踪等。 - **Sensor SDK**:允许访问和处理来自硬件传感器的数据,例如RGB-D图像和深度信息。 开发者使用OpenNI时,可以利用其API来创建...
安装 Kinect 需要安装多个依赖项和工具,包括 Xcode、Command Line Tool、XQuartz、CMake、MacPorts、Libtool、libusb、OpenNI-Bin-Dev-MacOSX-v1.5.4.0、SensorKinect-unstable、NITE-Bin-Dev-MacOSXcode-v1.5.2.21...
- **定义**:NITE是由PrimeSense提供的OpenNI的中间件,负责分析Kinect捕捉到的数据,并将其转换成人体骨骼、手势等信息。 - **作用**:若只需读取深度信息和图像信息,可选择不安装。 - **获取方式**:从Prime...
4. **Primesense Nite**:是OpenNI的一部分,提供了手势识别、骨架追踪等功能。 在标签中提到的"OPENNI2",是OpenNI的第二个主要版本,它引入了若干改进和新特性,比如更好的性能、更多的硬件支持和更优化的API。与...
例如,通过CL-NUI库可以方便地接入Kinect,获取深度数据和图像数据,甚至控制Kinect的底座马达和LED灯。 然而,对于更复杂的任务,如人体姿态识别和骨架提取,需要利用OpenNI(开放自然交互)框架。OpenNI为开发者...
- NITE(Natural Interaction for Tracking and Expression)是由PrimeSense提供的OpenNI中间件,处理Kinect捕捉的数据,转换为骨骼追踪和手势识别等信息。 3. **安装步骤**: - 首先,从官方网站下载OpenNI的...