本文参考http://www.cnblogs.com/tornadomeet/archive/2012/09/27/2706417.html
环境:ubuntu14.10+QT5.3+QT creator
注意代码中的assimp部分还没用到,是我自己使用测试的
在原文的基础上,加入了一些头文件,不然编译失败,不含错误处理部分:
#include <QtGui>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QApplication>
#include <ni/XnCppWrapper.h> //包含OpenNI的头文件
//for assimp
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <iostream>
using namespace std;
using namespace xn;//使用OpenNI库中的命名空间
//全局的OpenNI object
Context g_context;
ImageGenerator g_image_generator;
DepthGenerator g_depth_generator;
//全局的Qt Object
QGraphicsPixmapItem *g_image_map;
QGraphicsPixmapItem *g_depth_map;
//CTimer类的定义
class CTimer : public QObject
{
public:
void start() {
g_context.StartGeneratingAll();//开启设备读取数据的开关
startTimer(33);//使用startTimer()启动定时器,每当时间到时会自动调用timerEvent()函数
}
private:
void timerEvent(QTimerEvent *) {
g_context.WaitAndUpdateAll();//更新数据
//颜色数据
ImageMetaData image_map;
g_image_generator.GetMetaData(image_map);
//为g_image_map设置图片,图片的数据来源于外部硬件设备
g_image_map->setPixmap(QPixmap::fromImage(QImage(image_map.Data(), image_map.XRes(),
image_map.YRes(), QImage::Format_RGB888)));
//深度数据
DepthMetaData depth_map;
g_depth_generator.GetMetaData(depth_map);
XnDepthPixel max_depth_value = depth_map.ZRes();
QImage depth_img(depth_map.XRes(), depth_map.YRes(), QImage::Format_ARGB32);//格式为ARGB32型的
for(unsigned int i = 0; i < depth_map.XRes(); i++)
for(unsigned int j = 0; j < depth_map.YRes(); j++)
{
XnDepthPixel depth_value_ij = depth_map(i, j);//获取x,y处的坐标值
if(depth_value_ij == 0) {
depth_img.setPixel(i, j, qRgba(0, 0, 0, 0));
}//如果捕捉不到深度信息,则将其设置为0
else {
float fscale = 1.0f*depth_value_ij/max_depth_value;//当前深度的比例因子
depth_img.setPixel(i, j, qRgba(255*(1-fscale), 0, 255*fscale, 255*(1-fscale)));
}
}
g_depth_map->setPixmap(QPixmap::fromImage(depth_img));
}
};
bool import(const std::string &pFile);
int main(int argc, char **argv)
{
QApplication app(argc, argv);
g_context.Init();//context初始化
g_context.SetGlobalMirror(true);//设置全局镜像,就像照镜子一样,与设置为false时的2张图片镜像
XnMapOutputMode xmode;//定义图像的输出模式
xmode.nXRes = 640;//x方向分辨率
xmode.nYRes = 480;//y方向分辨率
xmode.nFPS = 30;//帧率
//设置颜色节点属性
g_image_generator.Create(g_context);
g_image_generator.SetMapOutputMode(xmode);
//设置深度节点属性
g_depth_generator.Create(g_context);
g_depth_generator.SetMapOutputMode(xmode);
//视觉校正,否则深度图和颜色图感应到的区域不能一一对应
g_depth_generator.GetAlternativeViewPointCap().SetViewPoint(g_image_generator);
//Qt场景设置
QGraphicsScene scene;
g_image_map = scene.addPixmap(QPixmap());
g_image_map->setZValue(1);//设置为z方向上的第1层
g_depth_map = scene.addPixmap(QPixmap());
g_depth_map->setZValue(2);//设置为z方向上的第2层
//Qt视图创建
QGraphicsView view(&scene);
view.resize(660, 500);
//设置定时器,每隔一段时间读取kinect的颜色信息和深度信息
CTimer timer;
timer.start();
view.show();
const string path="/home/thu/code/project/qtmotion/abao.obj";
import(path);
return app.exec();
}
bool import(const std::string &pFile)
{
// 定义一个导入器
Assimp::Importer importer;
// 使用导入器导入选定的模型文件
const aiScene* scene = importer.ReadFile( pFile,
aiProcess_CalcTangentSpace| //后处理标志,自动计算切线和副法线
aiProcess_Triangulate| //后处理标志,自动将四边形面转换为三角面
aiProcess_JoinIdenticalVertices| //后处理标志,自动合并相同的顶点
aiProcess_SortByPType); //后处理标志,将不同图元放置到不同的模型中去,图片类型可能是点、直线、三角形等
//更多后处理标志可以参考Assimp的文档
if( !scene)
{
//导入错误,获取错误信息并进行相应的处理
//DoTheErrorLogging( importer.GetErrorString());
cout<<"Error loading the obj file"<<endl;
return false;
}
// 根据需要获取scene中的模型数据,各种数据的获取方式可以参考Assimp的文档
//DoTheSceneProcessing( scene);
cout<<"import the scene"<<endl;
return true;
}
包含错误处理部分的代码如下,加入了qmessagebox的头文件,不然会报错
#include <QtGui>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QApplication>
#include <qmessagebox.h>
#include <ni/XnCppWrapper.h> //包含OpenNI的头文件
//for assimp
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <iostream>
using namespace std;
using namespace xn;//使用OpenNI库中的命名空间
//全局的OpenNI object
XnStatus g_status;
Context g_context;
ImageGenerator g_image_generator;
DepthGenerator g_depth_generator;
bool g_has_image_generator = true;
//全局的Qt Object
QGraphicsPixmapItem *g_image_map;
QGraphicsPixmapItem *g_depth_map;
//CTimer类的定义
class CTimer : public QObject
{
public:
void start() {
g_status = g_context.StartGeneratingAll();//开启设备读取数据的开关
if(g_status == XN_STATUS_OK) {
startTimer(33);//使用startTimer()启动定时器,每当时间到时会自动调用timerEvent()函数
}
else {
QMessageBox::critical(NULL, "Create Data Error!", xnGetStatusString(g_status));//显示创建数据失败,该消息框没有父窗口
}
}
private:
void timerEvent(QTimerEvent *) {
g_context.WaitAndUpdateAll();//更新数据
//颜色数据
if(g_has_image_generator) {
ImageMetaData image_map;
g_image_generator.GetMetaData(image_map);
//为g_image_map设置图片,图片的数据来源于外部硬件设备
g_image_map->setPixmap(QPixmap::fromImage(QImage(image_map.Data(), image_map.XRes(),
image_map.YRes(), QImage::Format_RGB888)));
}
//深度数据
DepthMetaData depth_map;
g_depth_generator.GetMetaData(depth_map);
XnDepthPixel max_depth_value = depth_map.ZRes();
QImage depth_img(depth_map.XRes(), depth_map.YRes(), QImage::Format_ARGB32);//格式为ARGB32型的
for(unsigned int i = 0; i < depth_map.XRes(); i++)
for(unsigned int j = 0; j < depth_map.YRes(); j++)
{
XnDepthPixel depth_value_ij = depth_map(i, j);//获取x,y处的坐标值
if(depth_value_ij == 0) {
depth_img.setPixel(i, j, qRgba(0, 0, 0, 0));
}//如果捕捉不到深度信息,则将其设置为0
else {
float fscale = 1.0f*depth_value_ij/max_depth_value;//当前深度的比例因子
depth_img.setPixel(i, j, qRgba(255*(1-fscale), 0, 255*fscale, 255*(1-fscale)));
}
}
g_depth_map->setPixmap(QPixmap::fromImage(depth_img));
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
g_status = g_context.Init();//context初始化
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, "Context Initial Error!", xnGetStatusString(g_status));
return -1;
}
// g_context.SetGlobalMirror(true);//设置全局镜像,就像照镜子一样,与设置为false时的2张图片镜像
XnMapOutputMode xmode;//定义图像的输出模式
xmode.nXRes = 640;//x方向分辨率
xmode.nYRes = 480;//y方向分辨率
xmode.nFPS = 30;//帧率
//设置颜色节点属性
g_status = g_image_generator.Create(g_context);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, "Image map create failed", xnGetStatusString(g_status));
g_has_image_generator = false;
}
if( g_has_image_generator ) {
g_status = g_image_generator.SetMapOutputMode(xmode);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, "Image map output mode error!", xnGetStatusString(g_status));
return -1;
}
}
//设置深度节点属性
g_status = g_depth_generator.Create(g_context);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, "Depth map create failed", xnGetStatusString(g_status));
return -1;
}
g_status = g_depth_generator.SetMapOutputMode(xmode);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, "Depth map output mode error!", xnGetStatusString(g_status));
return -1;
}
if(g_has_image_generator)//视觉校正,否则深度图和颜色图感应到的区域不能一一对应
;//g_depth_generator.GetAlternativeViewPointCap().SetViewPoint(g_image_generator);
//Qt场景设置
QGraphicsScene scene;
g_image_map = scene.addPixmap(QPixmap());
g_image_map->setZValue(1);//设置为z方向上的第1层
g_depth_map = scene.addPixmap(QPixmap());
g_depth_map->setZValue(2);//设置为z方向上的第2层
//Qt视图创建
QGraphicsView view(&scene);
view.resize(660, 500);
//设置定时器,每隔一段时间读取kinect的颜色信息和深度信息
CTimer timer;
timer.start();
view.show();
return app.exec();
}
程序逻辑跟原文一样,感谢原作者!