本文改编自http://www.cnblogs.com/tornadomeet/archive/2012/09/29/2708029.html
对原文的程序架构进行了改编,符合面向对象的思想
头文件:ckinectreader.h copenni.h
源文件:ckinectreader.cpp copenni.cpp main.cpp
代码贴在下面
copenni.h
#ifndef COPENNI_H
#define COPENNI_H
#include <ni/XnCppWrapper.h>
#include <QtGui>
#include <QApplication>
#include <qmessagebox.h>
#include <iostream>
using namespace std;
using namespace xn;
class COpenNI
{
public:
COpenNI();
~COpenNI();
bool Initial();
bool Start();
bool UpdateData();
DepthMetaData depth_metadata;
ImageMetaData image_metadata;
private:
//return true if wrong,else return false
bool CheckError(const char* error);
XnStatus status;
Context context;
DepthGenerator depth_generator;
ImageGenerator image_generator;
};
#endif // COPENNI_Hckinectreader.h
#ifndef CKINECTREADER_H
#define CKINECTREADER_H
#include "copenni.h"
#include <QObject>
#include <QtGui>
#include <QDebug>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <ni/XnCppWrapper.h>
#include <iostream>
using namespace std;
class CKinectReader : public QObject
{
//to do things from here
public:
CKinectReader(COpenNI &openni,QGraphicsScene &scene):openni(openni),scene(scene){
test=0.0;
}
~CKinectReader();
bool Start(int interval=33);
float test;
private:
void timerEvent(QTimerEvent *);
COpenNI &openni;
QGraphicsScene &scene;
QGraphicsPixmapItem *image_item;
QGraphicsPixmapItem *depth_item;
uchar *p_depth_argb;
};
#endif // CKINECTREADER_H
copenni.cpp
#include "copenni.h"
COpenNI::COpenNI()
{
}
COpenNI::~COpenNI()
{
context.Release();
}
bool COpenNI::Initial()
{
//initialize
status=context.Init();
if(CheckError("Context initial failed!")){
return false;
}
context.SetGlobalMirror(true);//设置镜像
//产生图片node
status = image_generator.Create(context);
if(CheckError("Create image generator error!")) {
return false;
}
//产生深度node
status = depth_generator.Create(context);
if(CheckError("Create depth generator error!")) {
return false;
}
//视角校正
status = depth_generator.GetAlternativeViewPointCap().SetViewPoint(image_generator);
if(CheckError("Can't set the alternative view point on depth generator")) {
return false;
}
return true;
}
bool COpenNI::Start() {
status = context.StartGeneratingAll();
if(CheckError("Start generating error!")) {
return false;
}
return true;
}
bool COpenNI::UpdateData() {
status = context.WaitNoneUpdateAll();
if(CheckError("Update date error!")) {
return false;
}
//获取数据
image_generator.GetMetaData(image_metadata);
depth_generator.GetMetaData(depth_metadata);
return true;
}
bool COpenNI::CheckError(const char* error) {
if(status != XN_STATUS_OK ) {
QMessageBox::critical(NULL, error, xnGetStatusString(status));
cerr << error << ": " << xnGetStatusString( status ) << endl;
return true;
}
return false;
}
ckinectreader.cpp
#include "ckinectreader.h"
CKinectReader::~CKinectReader(){
scene.removeItem(image_item);
scene.removeItem(depth_item);
delete[] p_depth_argb;
}
bool CKinectReader::Start(int interval) {
openni.Start();//因为在调用CKinectReader这个类的之前会初始化好的,所以这里直接调用Start了
image_item = scene.addPixmap(QPixmap());
image_item->setZValue(1);
depth_item = scene.addPixmap(QPixmap());
depth_item->setZValue(2);
openni.UpdateData();
p_depth_argb = new uchar[4*openni.depth_metadata.XRes()*openni.depth_metadata.YRes()];
startTimer(interval);//这里是继承QObject类,因此可以调用该函数
return true;
}
void CKinectReader::timerEvent(QTimerEvent *) {
openni.UpdateData();
//这里使用const,是因为右边的函数返回的值就是const类型的
const XnDepthPixel *p_depth_pixpel = openni.depth_metadata.Data();
unsigned int size = openni.depth_metadata.XRes()*openni.depth_metadata.YRes();
//找深度最大值点
XnDepthPixel max_depth = *p_depth_pixpel;
for(unsigned int i = 1; i < size; ++i)
if(p_depth_pixpel[i] > max_depth )
max_depth = p_depth_pixpel[i];
test = max_depth;
//将深度图像格式归一化到0~255
int idx = 0;
for(unsigned int i = 1; i < size; ++i) {
//一定要使用1.0f相乘,转换成float类型,否则该工程的结果会有错误,因为这个要么是0,要么是1,0的概率要大很多
float fscale = 1.0f*(*p_depth_pixpel)/max_depth;
if((*p_depth_pixpel) != 0) {
p_depth_argb[idx++] = 255*(1-fscale); //蓝色分量
p_depth_argb[idx++] = 0; //绿色分量
p_depth_argb[idx++] = 255*fscale; //红色分量,越远越红
p_depth_argb[idx++] = 255*(1-fscale); //距离越近,越不透明
}
else {
p_depth_argb[idx++] = 0;
p_depth_argb[idx++] = 0;
p_depth_argb[idx++] = 0;
p_depth_argb[idx++] = 255;
}
++p_depth_pixpel;//此处的++p_depth_pixpel和p_depth_pixpel++是一样的
}
//往item中设置图像色彩数据
image_item->setPixmap(QPixmap::fromImage(
QImage(openni.image_metadata.Data(), openni.image_metadata.XRes(), openni.image_metadata.YRes(),
QImage::Format_RGB888)));
//往item中设置深度数据
depth_item->setPixmap(QPixmap::fromImage(
QImage(p_depth_argb, openni.depth_metadata.XRes(), openni.depth_metadata.YRes()
, QImage::Format_ARGB32)));
}
main.cpp
#include <QtGui/QtGui>
#include <QDebug>
#include <QGraphicsView>
#include "ckinectreader.h"
int main(int argc, char **argv)
{
COpenNI openni;
if(!openni.Initial())//初始化返回1表示初始化成功
return 1;
QApplication app(argc, argv);
QGraphicsScene scene;
QGraphicsView view;
view.setScene(&scene);
view.resize(650, 540);
view.show();
CKinectReader kinect_reader(openni, scene);
kinect_reader.Start();//启动,读取数据
qDebug() << kinect_reader.test;
return app.exec();
}程序逻辑,跟原文相同!
可以直接运行。
本文介绍了一种利用OpenNI库和Kinect传感器进行图像和深度数据采集的方法。通过面向对象的设计,实现了图像数据和深度数据的实时更新,并在Qt环境中进行可视化展示。

3839

被折叠的 条评论
为什么被折叠?



