OpenNI支持的图像格式比较单一
xn::DepthMetaData depthMD;
xn::ImageMetaData imageMD;
需要用OpenCV进行下一步操作,则需要将DepthMetaData、ImageMetaData转换为Mat
经过试验,成功实现了三种方法:
#include <stdlib.h> #include <iostream> #include <string> #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 ) { XnStatus result = XN_STATUS_OK; xn::DepthMetaData depthMD; xn::ImageMetaData imageMD; //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); char key=0; //【2】 // context xn::Context context; result = context.Init(); CheckOpenNIError( result, "initialize context" ); // creategenerator xn::DepthGenerator depthGenerator; result = depthGenerator.Create( context ); CheckOpenNIError( result, "Create depth generator" ); xn::ImageGenerator imageGenerator; result = imageGenerator.Create( context ); CheckOpenNIError( result, "Create image generator" ); //【3】 //map mode XnMapOutputMode mapMode; mapMode.nXRes = 640; mapMode.nYRes = 480; mapMode.nFPS = 30; result = depthGenerator.SetMapOutputMode( mapMode ); result = imageGenerator.SetMapOutputMode( mapMode ); //【4】 // correct view port depthGenerator.GetAlternativeViewPointCap().SetViewPoint( imageGenerator ); //【5】 //read data result = context.StartGeneratingAll(); //【6】 result = context.WaitNoneUpdateAll(); while((key!=27) && !(result = context.WaitNoneUpdateAll()) ) { //get meta data depthGenerator.GetMetaData(depthMD); imageGenerator.GetMetaData(imageMD); //---------------------------------------------------------------------- //---------------转换为Mat操作,3种方式---------------------------- //------------------------------------------------------------------------ if(depthMD.Data()!=NULL) { //方法【1】通过Mat定义 //convert ImageMetaData to Mat uchar *q = (uchar *) imageMD.Data(); Mat rgbMat1(480,640,CV_8UC3,q); Mat rgbMatShow1; cvtColor(rgbMat1,rgbMatShow1,CV_RGB2BGR); imshow("testColorMat",rgbMatShow1); //convert DepthMetaData to Mat unsigned short* p = (unsigned short*) depthMD.Data(); Mat depthMat1(480,640,CV_16SC1,p); Mat depthMatShow1(480,640,CV_8UC1); convertScaleAbs(depthMat1,depthMatShow1,255/4096.0);//这一步很重要; normalize(depthMatShow1,depthMatShow1,255,0,CV_MINMAX); imshow("testDepthMat",depthMatShow1); //方法【2】通过坐标(x,y),ImageMetaData貌似不太支持; Mat depthMat2(480,640,CV_16SC1); Mat depthMatShow2(480,640,CV_8UC1); UINT16* depth_p; for (int y=0; y<480; y++) { depth_p = depthMat2.ptr<UINT16>(y); for (int x=0; x<640; x++) { depth_p[x]=(UINT16)depthMD(x,y);//核心赋值 } } convertScaleAbs(depthMat2,depthMatShow2,255/4096.0);//这一步很重要; normalize(depthMatShow2,depthMatShow2,255,0,CV_MINMAX); imshow("testDepthMat2",depthMatShow2); //方法【3】通过指针操作; //RGB Mat rgbMat3(480,640,CV_8UC3); Mat rgbMatShow3; uchar *rgb_p; UINT8 *src_p; src_p = (UINT8*) imageMD.Data(); for (int y=0; y<480; y++) { rgb_p = rgbMat3.ptr<uchar>(y); for (int x=0; x<640; x++) { *rgb_p++ =(uchar) *src_p++; *rgb_p++ =(uchar) *src_p++; *rgb_p++ =(uchar) *src_p++; } } cvtColor(rgbMat3,rgbMatShow3,CV_RGB2BGR); imshow("testColorMat3",rgbMatShow3); Mat depthMat3(480,640,CV_16SC1); Mat depthMatShow3(480,640,CV_8UC1); UINT16* depthSrc_p; uchar* depth3_p; depthSrc_p = (UINT16*)depthMD.Data(); for (int y=0; y<480; y++) { depth3_p = depthMatShow3.ptr<uchar>(y); for (int x=0; x<640; x++) { depth3_p[x]= (uchar)((*depthSrc_p)*255/4096); depthSrc_p++; } } //convertScaleAbs(depthMat3,depthMatShow3,255/4096.0);//这一步很重要; normalize(depthMatShow3,depthMatShow3,255,0,CV_MINMAX); imshow("testDepthMat3",depthMatShow3); } //OpenCV output // ---------------------------------------------------------------------- // ---------------转换为IplImage操作---------------------------- // ------------------------------------------------------------------------ memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2); 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); } }