苦逼了好几天终于这些环境给配置好了,系统64位的配置起来各种坑。希望大家看了能少走点弯路,我只是刚入门的菜鸡,勿喷!
素材我就不提供了,应该都找的到资源的。下面开始配置环境了:
1.0 首先安装好openni,再接着安装NITE。前面两个顺序比较重要,我看了好多教程都是这样的说的,具体原因我也不知道了。接着把opencv安装好,因为opencv安装的包很大不建议放在系统盘下。我这里安装的路径是
接下来为opencv配置好 环境变量
备注:X64是64位的 X86是32位下(不管是你的系统是32还是64的都配置上,到时候在编译器在win32和X64间切换就不用担心这一块出问题了)
更详细的opencv配置的博客大家可以看看这个 http://blog.csdn.net/huang9012/article/details/21811129
openni 的具体配置:http://blog.csdn.net/chenxin_130/article/details/8580636
2.0 重头戏就是VS2013配置了
第一步 在配置环境的时候,我想了一下配置环境这么苦逼的事情。要是我每新建一个项目都要配置一次。妈蛋那不是要炸了!所以我找到了 vs2013中属性管理器 (视图栏下=》其他窗口=》属性管理器)
鼠标右键点开NuiContainer(这个是我的)项目 新建个属性表(我这里有X64 的属性配置,是因为是64位系统 安装的openNI NITE 都是64位 所以必须要用X64平台进行统一配置,配置好的文件 在你新建项目的,添加现有属性配置表就可以加载好已经配置好环境了)
双击你创建好的属性表进行配置:
VC++目录配置:Openni和NITE是你安装在C盘下的路径
C/C++:
链接器:
在Debug和Release两种不同的模式下配置的不一样:Debug模式下把xxxxxxd.lib加入进去,Release模式下把xxxxx.lib加入进去
后面再把这两个lib给加上去 OpenNI2.lib NiTE2.lib
把 C:\Program Files\OpenNI2\Redist 和C:\Program Files\PrimeSense\NiTE2\Redist下所有文件拷贝到你的新建项目下的工程文件夹下
opencv : 在X64的平台上运行时,opencv库目录要换成E:\Opencv\opencv\build\x64\vc12\lib 在win32下换成 E:\Opencv\opencv\build\x86\vc12\lib
// YeNite2SimpleUsingOpenCV.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
#include <iostream>
// OpenCV 头文件
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <OpenNI.h>
#include <NiTE.h>
using namespace std;
using namespace openni;
using namespace nite;
int main(int argc, char **argv)
{
// 初始化OpenNI
OpenNI::initialize();
// 打开Kinect设备
Device mDevice;
mDevice.open(ANY_DEVICE);
// 创建深度数据流
VideoStream mDepthStream;
mDepthStream.create(mDevice, SENSOR_DEPTH);
// 设置VideoMode模式
VideoMode mDepthMode;
mDepthMode.setResolution(640, 480);
mDepthMode.setFps(30);
mDepthMode.setPixelFormat(PIXEL_FORMAT_DEPTH_1_MM);
mDepthStream.setVideoMode(mDepthMode);
// 同样的设置彩色数据流
VideoStream mColorStream;
mColorStream.create(mDevice, SENSOR_COLOR);
// 设置VideoMode模式
VideoMode mColorMode;
mColorMode.setResolution(640, 480);
mColorMode.setFps(30);
mColorMode.setPixelFormat(PIXEL_FORMAT_RGB888);
mColorStream.setVideoMode(mColorMode);
// 设置深度图像映射到彩色图像
mDevice.setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR);
// 为了得到骨骼数据,先初始化NiTE
NiTE::initialize();
// 创建用户跟踪器
UserTracker mUserTracker;
mUserTracker.create(&mDevice);
// Control the smoothing factor of the skeleton joints. Factor should be between 0 (no smoothing at all) and 1 (no movement at all)
mUserTracker.setSkeletonSmoothingFactor(0.1f);
// 创建User彩色图像显示
cv::namedWindow("User Image", CV_WINDOW_AUTOSIZE);
// 环境初始化后,开始获取深度数据流和彩色数据流
mDepthStream.start();
mColorStream.start();
while (true)
{
// 创建OpenCV::Mat,用于显示彩色数据图像
cv::Mat cImageBGR;
// 读取彩色图像数据帧信息流
VideoFrameRef mColorFrame;
mColorStream.readFrame(&mColorFrame);
// 将彩色数据流转换为OpenCV格式,记得格式是:CV_8UC3(含R\G\B)
const cv::Mat mImageRGB(mColorFrame.getHeight(), mColorFrame.getWidth(),
CV_8UC3, (void*)mColorFrame.getData());
// RGB ==> BGR
cv::cvtColor(mImageRGB, cImageBGR, CV_RGB2BGR);
// 读取User用户数据帧信息流
UserTrackerFrameRef mUserFrame;
mUserTracker.readFrame(&mUserFrame);
// 得到Users信息
const nite::Array<UserData>& aUsers = mUserFrame.getUsers();
for (int i = 0; i < aUsers.getSize(); ++i)
{
const UserData& rUser = aUsers[i];
// 检查用户状态
if (rUser.isNew())
{
// 开始对该用户的骨骼跟踪
mUserTracker.startSkeletonTracking(rUser.getId());
}
if (rUser.isVisible())
{
// 得到用户骨骼数据
const Skeleton& rSkeleton = rUser.getSkeleton();
// 检查骨骼状态是否为“跟踪状态”
if (rSkeleton.getState() == SKELETON_TRACKED)
{
// 得到15个骨骼数据
SkeletonJoint aJoints[15];
aJoints[0] = rSkeleton.getJoint(JOINT_HEAD);
aJoints[1] = rSkeleton.getJoint(JOINT_NECK);
aJoints[2] = rSkeleton.getJoint(JOINT_LEFT_SHOULDER);
aJoints[3] = rSkeleton.getJoint(JOINT_RIGHT_SHOULDER);
aJoints[4] = rSkeleton.getJoint(JOINT_LEFT_ELBOW);
aJoints[5] = rSkeleton.getJoint(JOINT_RIGHT_ELBOW);
aJoints[6] = rSkeleton.getJoint(JOINT_LEFT_HAND);
aJoints[7] = rSkeleton.getJoint(JOINT_RIGHT_HAND);
aJoints[8] = rSkeleton.getJoint(JOINT_TORSO);
aJoints[9] = rSkeleton.getJoint(JOINT_LEFT_HIP);
aJoints[10] = rSkeleton.getJoint(JOINT_RIGHT_HIP);
aJoints[11] = rSkeleton.getJoint(JOINT_LEFT_KNEE);
aJoints[12] = rSkeleton.getJoint(JOINT_RIGHT_KNEE);
aJoints[13] = rSkeleton.getJoint(JOINT_LEFT_FOOT);
aJoints[14] = rSkeleton.getJoint(JOINT_RIGHT_FOOT);
// 将骨骼3D坐标转换为深度坐标下骨骼位置坐标,并保存在数组中
cv::Point2f aPoint[15];
for (int s = 0; s < 15; ++s)
{
const Point3f& rPos = aJoints[s].getPosition();
mUserTracker.convertJointCoordinatesToDepth(
rPos.x, rPos.y, rPos.z,
&(aPoint[s].x), &(aPoint[s].y));
}
//在彩色图像中画出骨骼间的连接线
cv::line(cImageBGR, aPoint[0], aPoint[1], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[1], aPoint[2], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[1], aPoint[3], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[2], aPoint[4], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[3], aPoint[5], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[4], aPoint[6], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[5], aPoint[7], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[1], aPoint[8], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[8], aPoint[9], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[8], aPoint[10], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[9], aPoint[11], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[10], aPoint[12], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[11], aPoint[13], cv::Scalar(255, 0, 0), 3);
cv::line(cImageBGR, aPoint[12], aPoint[14], cv::Scalar(255, 0, 0), 3);
// 同样的在彩色图像中骨骼位置上画“圆”
for (int s = 0; s < 15; ++s)
{
if (aJoints[s].getPositionConfidence() > 0.5)
cv::circle(cImageBGR, aPoint[s], 3, cv::Scalar(0, 0, 255), 2);
else
cv::circle(cImageBGR, aPoint[s], 3, cv::Scalar(0, 255, 0), 2);
}
}
}
}
// 显示图像
cv::imshow("User Image", cImageBGR);
// 按键“q”退出循环
if (cv::waitKey(1) == 'q')
break;
}
// 先销毁User跟踪器
mUserTracker.destroy();
// 销毁彩色数据流和深度数据流
mColorStream.destroy();
mDepthStream.destroy();
// 关闭Kinect设备
mDevice.close();
// 关闭NITE和OpenNI环境
NiTE::shutdown();
OpenNI::shutdown();
return 0;
}
测试代码如上
运行结果效果图: