温故而知新——NITE 2的基本使用主要包括以下几个步骤:

1. 初始化NITE环境: nite::NiTE::initialize();

2. 创建User跟踪器: nite::UserTracker mUserTracker; mUserTracker.create();

3. 创建并读取User Frame信息:nite::UserTrackerFrameRef mUserFrame; mUserTracker.readFrame( &mUserFrame );

4. 从User Frame信息中获取User信息:  const nite::Array<nite::UserData>& aUsers = mUserFrame.getUsers();然后根据User信息开始人体骨骼跟踪识别。

5. 释放Frame信息:mUserFrame.release();

6. 关闭跟踪器:mUserTracker.destroy();

7. 最后关闭NITE环境:nite::NiTE::shutdown();

下面是简单的右手骨骼坐标跟踪,并显示右手坐标信息的程序代码:

// YeNITE2SimpleUsingOpenCV_Skeleton.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>// 载入NiTE.h头文件
#include <NiTE.h>// using namespace
using namespace std;int main( int argc, char** argv )
{// 初始化NITE
    nite::NiTE::initialize();// 创建User跟踪器
    nite::UserTracker mUserTracker;mUserTracker.create();nite::UserTrackerFrameRef mUserFrame;for( int i = 0; i < 1000; ++ i ){// 读取User Frame信息mUserTracker.readFrame( &mUserFrame );// 从User Frame信息中获取User信息const nite::Array<nite::UserData>& aUsers = mUserFrame.getUsers();// Frame中User的个数for( int i = 0; i < aUsers.getSize(); ++ i ){const nite::UserData& rUser = aUsers[i];// 当有User用户出现在Kinect面前,则判断并显示if( rUser.isNew() ){cout << "New User [" << rUser.getId() << "] found." << endl;// 开始人体骨骼跟踪
                mUserTracker.startSkeletonTracking( rUser.getId() );}// 获取骨骼坐标const nite::Skeleton& rSkeleton = rUser.getSkeleton();if( rSkeleton.getState() == nite::SKELETON_TRACKED ){// 得到右手坐标const nite::SkeletonJoint& righthand= rSkeleton.getJoint( nite::JOINT_RIGHT_HAND );const nite::Point3f& position = righthand.getPosition();cout << "右手坐标: " << position.x << "/" << position.y << "/" << position.z << endl;}}}// 释放
    mUserFrame.release();      // 关闭跟踪器
    mUserTracker.destroy();// 关闭NITE环境
    nite::NiTE::shutdown();return 0;
}

程序执行结果如下:

但通过对上述程序代码观察发现,在对人体骨骼跟踪的时候,未做出(“投降”和“双手抱胸”)的动作,也可以获取骨骼坐标信息。难道在NITE2骨骼跟踪的时候,人体姿势检测是多余的吗?这个我的理解是:似乎姿势跟踪将会变成鸡肋(完全靠自己的想象。。。)。

接着借助于OpenCV等常用工具库,看看骨骼坐标在深度图像下的定位和显示效果,直接上代码:

// YeNite2SimpleUsingOpenCV.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>// 载入NiTE.h头文件
#include <NiTE.h>// 载入OpenCV头文件
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>using namespace std;
using namespace cv;int main( int argc, char** argv )
{// 初始化NITE
    nite::NiTE::initialize();// 创建User跟踪器nite::UserTracker* mUserTracker = new nite::UserTracker;mUserTracker->create();// 创建OpenCV图像窗口namedWindow( "Skeleton Image",  CV_WINDOW_AUTOSIZE );// 循环读取数据流信息并保存在HandFrameRef中
    nite::UserTrackerFrameRef mUserFrame;while( true ){// 读取Frame信息nite::Status rc = mUserTracker->readFrame(&mUserFrame);if (rc != nite::STATUS_OK){cout << "GetNextData failed" << endl;return 0;}// 将深度数据转换成OpenCV格式const cv::Mat mHandDepth( mUserFrame.getDepthFrame().getHeight(), mUserFrame.getDepthFrame().getWidth(), CV_16UC1, (void*)mUserFrame.getDepthFrame().getData());// 为了让深度图像显示的更加明显一些,将CV_16UC1 ==> CV_8U格式
        cv::Mat mScaledHandDepth, thresholdDepth;mHandDepth.convertTo( mScaledHandDepth, CV_8U, 255.0 / 10000 );// 二值化处理,为了显示效果明显cv::threshold(mScaledHandDepth, thresholdDepth, 50, 255, 0);// 从User Frame信息中获取User信息const nite::Array<nite::UserData>& aUsers = mUserFrame.getUsers();// Frame中User的个数for( int i = 0; i < aUsers.getSize(); ++ i ){const nite::UserData& rUser = aUsers[i];// 当有User用户出现在Kinect面前,则判断并显示if( rUser.isNew() ){cout << "New User [" << rUser.getId() << "] found." << endl;// 开始人体骨骼跟踪mUserTracker->startSkeletonTracking( rUser.getId() );}// 获取骨骼坐标const nite::Skeleton& rSkeleton = rUser.getSkeleton();if( rSkeleton.getState() == nite::SKELETON_TRACKED ){// 只得到前8个骨骼点坐标for(int i = 0; i < 8; i++){// 得到骨骼坐标const nite::SkeletonJoint& skeletonJoint= rSkeleton.getJoint((nite::JointType)i);const nite::Point3f& position = skeletonJoint.getPosition();float depth_x, depth_y;// 将骨骼点坐标映射到深度坐标中mUserTracker->convertJointCoordinatesToDepth(position.x, position.y, position.z, &depth_x, &depth_y);cv::Point point((int)depth_x, (int)depth_y);// 将获取的深度图像中相对应的坐标点重新赋值为255.即在深度图像中显示出各个骨骼点。thresholdDepth.at<uchar>(point) = 255;}// 显示图像cv::imshow( "Skeleton Image", thresholdDepth );}}// 终止快捷键if( cv::waitKey(1) == 'q')break;}// 关闭Frame
    mUserFrame.release();// 关闭跟踪器mUserTracker->destroy();// 关闭NITE环境
    nite::NiTE::shutdown();return 0;
}

上图: 图上“白点”就是骨骼点。

需要了解具体的骨骼点信息(位置、方向,以及可靠性等),可以看官网提供的参考文献。我觉得遗憾的是,目前提供的15个骨骼点坐标不包括了手腕等其它骨骼点、而且只能得到全身的,不能单独获取上半身骨骼坐标。

结合程序注释和之前的博文内容,我想最后一个程序应该挺好理解的。根据自己的感觉走,感觉写代码,没做封装、优化、重构,完全是面向过程,而且肯定还存在细节的问题,会在后面进一步优化的。

写的粗糙,欢迎指正批评~~~

转载于:https://www.cnblogs.com/yemeishu/archive/2013/01/16/2862514.html

谈谈NITE 2与OpenCV结合的第二个程序(提取人体骨骼坐标)相关推荐

  1. 谈谈NITE 2与OpenCV结合的第一个程序

    开始之前,让我们自己开始再熟练熟练NITE 2的基本使用,主要包括以下几个步骤: 1. 初始化NITE环境: nite::NiTE::initialize(); 2. 创建User跟踪器: nite: ...

  2. 谈谈NITE 2与OpenCV结合提取指尖坐标

    在谈谈NITE 2与OpenCV结合的第一个程序中,通过手心坐标能够粗略的截取手的图像信息,但还是有种意犹未尽的感觉,所以今天根据OpenCV常用的轮廓.凸包等图像处理函数,在此基础上,获得指尖坐标( ...

  3. 谈谈NiTE 2手部跟踪在彩色图像上的显示

    主要内容: NiTE2手部跟踪流程 代码演示 总结 一.NiTE2手部跟踪流程 我自己都感觉到天天在重复着相同的代码,但我觉得没什么不好的,对于新东西的学习只有在重复再重复的过程中,才能积累经验,较少 ...

  4. 谈谈NITE 2的第一个程序UserViewer

    我觉得学习一个新的API,最好的办法是学习它提供的Samples.今天根据自己的了解,分享我自己对新的NITE 2的了解,首先看看NITE2 中提供的UserViewer,将它提供的工程文件夹导入到V ...

  5. 如何用OpenCV自带的adaboost程序训练并检测目标

    http://www.cnblogs.com/easymind223/archive/2012/07/03/2574826.html OpenCV自带的adaboost程序能够根据用户输入的正样本集与 ...

  6. Python OpenCV GrabCut进行前景分割和提取

    Python OpenCV GrabCut进行前景分割和提取 1. 效果图 1.1 边界框GrabCut效果图 1.2 Mask GrabCut效果图 2. GrabCut原理 2.1 GrabCut ...

  7. python语言程序设计嵩天-python语言程序设计基础(嵩天版),第二章程序练习题...

    python语言程序设计基础(嵩天版),第二章程序练习题 欢迎访问江南烧酒的博客 2.2汇率兑换程序.按照1美元=6人民币汇率编写一个美元和人民币的双向兑换程序. """ ...

  8. OpenCV计算机视觉编程攻略之提取图片轮廓-使用Canny函数

    OpenCV计算机视觉编程攻略之提取图片轮廓-使用Canny函数,很方便..代码如下: #include <vector> #include <iostream> #inclu ...

  9. OpenCV使用dnn从图像中解析人体部位的实例(附完整代码)

    OpenCV使用dnn从图像中解析人体部位的实例 OpenCV使用dnn从图像中解析人体部位的实例 OpenCV使用dnn从图像中解析人体部位的实例 #include <opencv2/dnn. ...

最新文章

  1. 下载编译网站生成chm
  2. 实现3d图片移动_「3D建模」什么是动画和角色设计的3D索具?
  3. k8s总结(脑图图片)
  4. MySQL-04:数据内容操作-增删改查-基本命令笔记
  5. 弹窗要打开或保存来自_如何让 PopClip 支持印象笔记客户端:保存到印象笔记amp;高亮文字...
  6. 将表中的数据自动生成INSERT、UPDATE语句
  7. 【Express】 —利用 Express 托管静态文件
  8. lingo软件的基本使用方法_(PS软件)PHOTOSHOP基础操作和基本工具的使用
  9. 【读书笔记《Android游戏编程之从零开始》】10.游戏开发基础(View 游戏框架)
  10. 如何打开java jar文件怎么打开方式_Win10系统下jar文件如何打开?
  11. matlab求解微积分
  12. [解决方案]ios用fd抓包进app无网络
  13. 基于Java Web的权限管理系统的设计与实现
  14. 查看CentOS版本信息
  15. android 菜鸟面单打印_android studio 菜鸟实战项目 之 spnner实现
  16. 2022秋软工实践 团队展示与选题报告
  17. Android ANR原理代码分析(三)
  18. 计算机技术与软件专业技术资格(水平)考试岗位设置与描述
  19. vim 安装YouCompleteMe 插件
  20. 你也可以找到好工作(三)大结局

热门文章

  1. python打开中文文件名_[请教]python的中文文件名处理
  2. c语言中的关于数学问题的编程,C语言中具有代表性几种数学问题编程技巧探索.doc...
  3. Docker容器的使用方法
  4. 小学计算机课的活动设计方案,小学信息技术兴趣小组活动策划书三篇
  5. js中同时得到整数商及余数_苏教版小学数学二年级下册1.1有余数的除法讲解
  6. centos losf 安装_Linux Centos7部署环境安装-CentOS
  7. springboot + rabbitmq发送邮件(保证消息100%投递成功并被消费)
  8. tomcat server.xml各个端口的作用
  9. Linux下tmp文件夹的文件自动删除的问题(转)
  10. 【对比分析六】JavaScript中GET和POST的区别及使用场景