[置顶] 在QT下测试openni+opencv,显示采集的深度图和彩色图

在QT下测试openni+opencv,显示采集的深度图和彩色图

(1)      新建工程。

因为考虑到opencv可以直接调用函数显示图片,因此采用在QT下新建一个空工程。

 

(2)      配置.pro文件。

此步骤是建立在已配置好opencv库和openni库的基础上的,依次添加的库为:

INCLUDEPATH += /usr/local/include \

/usr/local/include/opencv \

/usr/local/include/opencv2 \

/usr/include/ni \

/usr/include/nite \

 

LIBS += /usr/local/lib/libopencv_highgui.so\

/usr/local/local/libopencv_core.so \

/usr/local/lib/libopencv_imgproc_so \

/usr/lib/libXnVNite_1_5_2.so \

/usr/lib/libOpenNI.so \

以上的库配置是根据个人的安装文件而来的,因为我安装的opencv是2.4.9版本的,然后Openni是1.0版本的,配置前查看自己的文件是否是这个名称。如何找文件的安装路径,在ubuntu下,一般opencv是安装在文件系统 /usr/local/lib/  路径,openni安装在 文件系统/usr/lib/下。

 

(3)      使用OpenNI读取颜色图和深度图的步骤如下:

a)        添加openni的头文件#include <XnCppWrapper.h>。

b)        定义一个Context对象,并调用该对象的Init()方法来进行初始化。

c)        用context创建生成器,包括深度图像和彩色图像生成器。

d)        定义一个XnMapOutputMode格式对象,设置好分图像分辨率和帧率。

e)        设置颜色和深度图的输出模式,调用的方法是SetMapOutputMode()。

f)         因为深度摄像头和彩色摄像头不在同一个地方,看出来的景物是有偏差的,因此必须对深度图像进行校正,校正的方法.GetAlternativeViewPointCap().SetViewPoint()。

g)        调用context对象的StartGeneratingAll()来开启设备读取数据开关。

h)        调用context对象的更新数据方法,比如WaitAndupdateAll()方法。

i)          定义颜色图和色彩图的ImageMetaData对象,并利用对应的节点对象的方法GetMetaData(),将获取到的数据保存到对应的ImageData对象中。

j)          如果需要将深度图转换成灰度图来显示,则需要自己将深度值转换成0~255的单通道或者多通道数据,然后直接用来显示。

 

(4)      程序实例测试

#include <stdlib.h>

#include <iostream>

#include <string>

//【1】XnCppWrapper.hopenni的头文件。

#include <XnCppWrapper.h>

#include "opencv/cv.h"

#include "opencv/highgui.h"

 

using namespace std;

using namespace cv;

 

void CheckOpenNIError( XnStatus result,string status )

{

         if(result != XN_STATUS_OK )

                   cerr<< status << " Error: " << xnGetStatusString(result ) << endl;

}

 

int main( int argc, char** argv )

{

         XnStatusresult = XN_STATUS_OK; 

         xn::DepthMetaDatadepthMD;

         xn::ImageMetaDataimageMD;

 

         //OpenCV

         IplImage* imgDepth16u=cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);

         IplImage*imgRGB8u=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);

         IplImage* depthShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);

         IplImage*imageShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);

         cvNamedWindow("depth",1);

         cvNamedWindow("image",1);

         charkey=0;

 

         //【2】

         //DepthGeneratorImageGenerator,前者是深度图像生成器,后者是彩色图像生成器。创建一个生成器,首先要初始化一个context上下文,然后把context作为create函数的参数,便可以创建生成器。

         xn::Contextcontext;

         result= context.Init();

         CheckOpenNIError(result, "initialize context" ); 

 

         //creategenerator 

         xn::DepthGeneratordepthGenerator; 

         result= depthGenerator.Create( context );

         CheckOpenNIError(result, "Create depth generator" ); 

         xn::ImageGeneratorimageGenerator;

         result= imageGenerator.Create( context );

         CheckOpenNIError(result, "Create image generator" );

 

         //【3】

         //XnMapOutputMode 用于设定生成器的参数

         XnMapOutputModemapMode;

         mapMode.nXRes= 640; 

         mapMode.nYRes= 480;

         mapMode.nFPS= 30;

         result= depthGenerator.SetMapOutputMode( mapMode ); 

         result= imageGenerator.SetMapOutputMode( mapMode ); 

 

         //【4】

       // correct view port,为什么要调整视角,因为kinect的三只眼长在不同的地方,深度摄像头和彩色摄像头看出来的景物是有偏差的。这里把深度生成器的视角转换成彩色摄像头的视角。

         depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator );

 

         //【5】

         //readdata

         result= context.StartGeneratingAll(); 

         //【6】不管数据有没有读到新数据,只管更新。

         result= context.WaitNoneUpdateAll(); 

 

         while((key!=27) && !(result = context.WaitNoneUpdateAll( ))  )

         { 

                   //getmeta data

                   depthGenerator.GetMetaData(depthMD);

                   imageGenerator.GetMetaData(imageMD);

 

                   //【7】

                   //OpenCVoutput

                   memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2); 

//void*memcpy(void *dest, const void *src, size_t n);

//从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

                   cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);

                   memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);

                   cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);

                   cvShowImage("depth",depthShow);

                   cvShowImage("image",imageShow);

                   key=cvWaitKey(20);

         }

 

         //destroy

         cvDestroyWindow("depth");

         cvDestroyWindow("image");

         cvReleaseImage(&imgDepth16u);

         cvReleaseImage(&imgRGB8u);

         cvReleaseImage(&depthShow);

         cvReleaseImage(&imageShow);

         context.StopGeneratingAll();

         context.Shutdown();

         return0;

}

显示:

[置顶] 在QT下测试openni+opencv,显示采集的深度图和彩色图_第1张图片

[置顶] 在QT下测试openni+opencv,显示采集的深度图和彩色图_第2张图片


保存图片可以采用直接保存,可以完整保存图片的大小尺寸等。如果只是为了演示等,可以直接截屏alt+printscreen,默认的格式是以png格式保存的。

 

(5)      参考的网站

比较权威的网站:http://blog.csdn.net/chenxin_130/article/details/6696187

你可能感兴趣的:(qt,opencv,openni,彩色图,深度图)