[转载]OpenNI的深度图显示

OpenNI的深度图显示有主要有两种方法:

1.深度值直接赋值方法(同上一篇):

缺点:深度图层次不明显,主要由于位移操作导致

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdlib.h>  
  2. #include <iostream>  
  3. #include <string>  
  4.   
  5. #include <XnCppWrapper.h>  
  6. #include "opencv/cv.h"  
  7. #include "opencv/highgui.h"  
  8.   
  9. using namespace std;  
  10. using namespace cv;  
  11.   
  12.   
  13. void CheckOpenNIError( XnStatus result, string status )  
  14. {   
  15.     if( result != XN_STATUS_OK )   
  16.         cerr << status << " Error: " << xnGetStatusString( result ) << endl;  
  17. }  
  18.   
  19. int main( int argc, char** argv )  
  20. {  
  21.     XnStatus result = XN_STATUS_OK;    
  22.     xn::DepthMetaData depthMD;  
  23.     xn::ImageMetaData imageMD;  
  24.   
  25.     //OpenCV  
  26.     IplImage*  imgDepth16u=cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);  
  27.     IplImage* imgRGB8u=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);  
  28.     IplImage*  depthShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);  
  29.     IplImage* imageShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);  
  30.     cvNamedWindow("depth",1);  
  31.     cvNamedWindow("image",1);  
  32.     char key=0;  
  33.   
  34.     //【2】  
  35.     // context   
  36.     xn::Context context;   
  37.     result = context.Init();   
  38.     CheckOpenNIError( result, "initialize context" );    
  39.   
  40.     // creategenerator    
  41.     xn::DepthGenerator depthGenerator;    
  42.     result = depthGenerator.Create( context );   
  43.     CheckOpenNIError( result, "Create depth generator" );    
  44.     xn::ImageGenerator imageGenerator;  
  45.     result = imageGenerator.Create( context );   
  46.     CheckOpenNIError( result, "Create image generator" );  
  47.   
  48.     //【3】  
  49.     //map mode    
  50.     XnMapOutputMode mapMode;   
  51.     mapMode.nXRes = 640;    
  52.     mapMode.nYRes = 480;   
  53.     mapMode.nFPS = 30;   
  54.     result = depthGenerator.SetMapOutputMode( mapMode );    
  55.     result = imageGenerator.SetMapOutputMode( mapMode );    
  56.   
  57.     //【4】  
  58.     // correct view port    
  59.     depthGenerator.GetAlternativeViewPointCap().SetViewPoint( imageGenerator );   
  60.   
  61.     //【5】  
  62.     //read data  
  63.     result = context.StartGeneratingAll();    
  64.     //【6】  
  65.     result = context.WaitNoneUpdateAll();    
  66.   
  67.   
  68.     while((key!=27) && !(result = context.WaitNoneUpdateAll()) )  
  69.     {  
  70.         //get meta data  
  71.         depthGenerator.GetMetaData(depthMD);   
  72.         imageGenerator.GetMetaData(imageMD);  
  73. //----------------------------------------------------------------------  
  74. //---------------转换为Mat操作,3种方式----------------------------  
  75. //------------------------------------------------------------------------  
  76.         if(depthMD.Data()!=NULL)  
  77.         {  
  78.             //方法【1】通过Mat定义  
  79.             //convert ImageMetaData to Mat  
  80.             uchar *q = (uchar *) imageMD.Data();  
  81.             Mat rgbMat1(480,640,CV_8UC3,q);  
  82.             Mat rgbMatShow1;  
  83.             cvtColor(rgbMat1,rgbMatShow1,CV_RGB2BGR);  
  84.             imshow("testColorMat",rgbMatShow1);  
  85.   
  86.             //convert DepthMetaData to Mat  
  87.             unsigned short* p = (unsigned short*)  depthMD.Data();  
  88.             Mat depthMat1(480,640,CV_16SC1,p);  
  89.             Mat depthMatShow1(480,640,CV_8UC1);  
  90.             convertScaleAbs(depthMat1,depthMatShow1,255/4096.0);//这一步很重要;  
  91.             normalize(depthMatShow1,depthMatShow1,255,0,CV_MINMAX);  
  92.             imshow("testDepthMat",depthMatShow1);  
  93.   
  94.             //方法【2】通过坐标(x,y),ImageMetaData貌似不太支持;  
  95.             Mat depthMat2(480,640,CV_16SC1);  
  96.             Mat depthMatShow2(480,640,CV_8UC1);  
  97.             UINT16* depth_p;  
  98.             for (int y=0; y<480; y++)  
  99.             {  
  100.                 depth_p = depthMat2.ptr<UINT16>(y);  
  101.                 for (int x=0; x<640; x++)  
  102.                 {  
  103.                     depth_p[x]=(UINT16)depthMD(x,y);//核心赋值  
  104.                 }  
  105.             }  
  106.             convertScaleAbs(depthMat2,depthMatShow2,255/4096.0);//这一步很重要;  
  107.             normalize(depthMatShow2,depthMatShow2,255,0,CV_MINMAX);  
  108.             imshow("testDepthMat2",depthMatShow2);  
  109.   
  110.             //方法【3】通过指针操作;  
  111.             //RGB  
  112.             Mat rgbMat3(480,640,CV_8UC3);  
  113.             Mat rgbMatShow3;  
  114.             uchar *rgb_p;  
  115.             UINT8 *src_p;  
  116.             src_p = (UINT8*) imageMD.Data();  
  117.             for (int y=0; y<480; y++)  
  118.             {  
  119.                 rgb_p = rgbMat3.ptr<uchar>(y);  
  120.                 for (int x=0; x<640; x++)  
  121.                 {  
  122.                     *rgb_p++ =(uchar) *src_p++;  
  123.                     *rgb_p++ =(uchar) *src_p++;  
  124.                     *rgb_p++ =(uchar) *src_p++;  
  125.                 }  
  126.             }  
  127.             cvtColor(rgbMat3,rgbMatShow3,CV_RGB2BGR);  
  128.             imshow("testColorMat3",rgbMatShow3);  
  129.   
  130.             Mat depthMat3(480,640,CV_16SC1);  
  131.             Mat depthMatShow3(480,640,CV_8UC1);  
  132.             UINT16* depthSrc_p;  
  133.             uchar* depth3_p;  
  134.             depthSrc_p = (UINT16*)depthMD.Data();  
  135.             for (int y=0; y<480; y++)  
  136.             {  
  137.                 depth3_p = depthMatShow3.ptr<uchar>(y);  
  138.                 for (int x=0; x<640; x++)  
  139.                 {  
  140.                     depth3_p[x]= (uchar)((*depthSrc_p)*255/4096);//  
  141.                     depthSrc_p++;  
  142.                 }  
  143.             }  
  144.             //convertScaleAbs(depthMat3,depthMatShow3,255/4096.0);//这一步很重要;  
  145.             normalize(depthMatShow3,depthMatShow3,255,0,CV_MINMAX);  
  146.             imshow("testDepthMat3",depthMatShow3);  
  147.   
  148.   
  149.         }  
  150.   
  151.         //OpenCV output  
  152. // ----------------------------------------------------------------------  
  153. // ---------------转换为IplImage操作----------------------------  
  154. // ------------------------------------------------------------------------  
  155.         memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);  
  156.         cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);  
  157.         memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);  
  158.         cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);  
  159.         cvShowImage("depth", depthShow);  
  160.         cvShowImage("image",imageShow);  
  161.         key=cvWaitKey(20);  
  162.           
  163.     }  
  164.   
  165. }  


2.通过NiSample的直方图赋值方法:

优点:生成的深度图层次比较明显。

代码附带深度阈值分割

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdlib.h>  
  2. #include <iostream>  
  3. #include <string>  
  4.   
  5. #include <XnCppWrapper.h>  
  6. #include "opencv/cv.h"  
  7. #include "opencv/highgui.h"  
  8.   
  9. using namespace std;  
  10. using namespace cv;  
  11.   
  12.   
  13. void CheckOpenNIError( XnStatus result, string status )  
  14. {   
  15.     if( result != XN_STATUS_OK )   
  16.         cerr << status << " Error: " << xnGetStatusString( result ) << endl;  
  17. }  
  18.   
  19. int main( int argc, char** argv )  
  20. {  
  21.     XnStatus result = XN_STATUS_OK;    
  22.     xn::DepthMetaData depthMD;  
  23.     xn::ImageMetaData imageMD;  
  24.   
  25.     //【2】  
  26.     // context   
  27.     xn::Context context;   
  28.     result = context.Init();   
  29.     CheckOpenNIError( result, "initialize context" );    
  30.     // creategenerator    
  31.     xn::DepthGenerator depthGenerator;    
  32.     result = depthGenerator.Create( context );   
  33.     CheckOpenNIError( result, "Create depth generator" );    
  34.     xn::ImageGenerator imageGenerator;  
  35.     result = imageGenerator.Create( context );   
  36.     CheckOpenNIError( result, "Create image generator" );  
  37.   
  38.     //【3】  
  39.     //map mode    
  40.     XnMapOutputMode mapMode;   
  41.     mapMode.nXRes = 640;    
  42.     mapMode.nYRes = 480;   
  43.     mapMode.nFPS = 30;   
  44.     result = depthGenerator.SetMapOutputMode( mapMode );    
  45.     result = imageGenerator.SetMapOutputMode( mapMode );    
  46.   
  47.     //【4】  
  48.     // correct view port  
  49.     // 若使用imageGenerator则深度图有一圈黑  
  50.     depthGenerator.GetAlternativeViewPointCap().SetViewPoint( depthGenerator );   
  51.   
  52.     //【5】  
  53.     //read data  
  54.     result = context.StartGeneratingAll();    
  55.       
  56.     //【6】  
  57.     result = context.WaitNoneUpdateAll();    
  58.   
  59.     Mat depthMat1u(480,640,CV_8UC1);  
  60.     Mat depthMat3u(480,640,CV_8UC3);  
  61.       
  62.   
  63.     char key=0;  
  64.     while((key!=27) && !(result = context.WaitNoneUpdateAll()) )  
  65.     {  
  66.   
  67.         //get meta data  
  68.         depthGenerator.GetMetaData(depthMD);   
  69.         imageGenerator.GetMetaData(imageMD);  
  70.   
  71.         //直接Mat赋值操作  
  72.         uchar *q = (uchar *) imageMD.Data();  
  73.         Mat rgbMat1(480,640,CV_8UC3,q);  
  74.         Mat rgbMatShow1;  
  75.         cvtColor(rgbMat1,rgbMatShow1,CV_RGB2BGR);  
  76.         imshow("testColorMat",rgbMatShow1);  
  77.   
  78.         //通过OpenNI Sample 中 NUISampleViewer 的 pDepthHist[*pDepth]操作.  
  79.         XnDepthPixel nZRes = depthMD.ZRes();  
  80.         float* pDepthHist = (float*)malloc(nZRes * sizeof(float));  
  81.   
  82.         const XnDepthPixel* pDepth = depthMD.Data();  
  83.         xnOSMemSet(pDepthHist, 0, nZRes*sizeof(float));  
  84.   
  85.         unsigned int nNumberOfPoints = 0;  
  86.         for (XnUInt y = 0; y < depthMD.YRes(); ++y)  
  87.         {  
  88.             for (XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth)  
  89.             {  
  90.                 if (*pDepth != 0)  
  91.                 {  
  92.                     pDepthHist[*pDepth]++;  
  93.                     nNumberOfPoints++;  
  94.                 }  
  95.             }  
  96.         }  
  97.   
  98.         for (int nIndex=1; nIndex<nZRes; nIndex++)  
  99.         {  
  100.             pDepthHist[nIndex] += pDepthHist[nIndex-1];  
  101.         }  
  102.           
  103.         if (nNumberOfPoints)  
  104.         {  
  105.             for (int nIndex=1; nIndex<nZRes; nIndex++)  
  106.             {  
  107.                 pDepthHist[nIndex] = (unsigned int)(256 * (1.0f - (pDepthHist[nIndex] / nNumberOfPoints)));  
  108.             }  
  109.         }  
  110.   
  111.         const XnDepthPixel* pDepthRow = depthMD.Data();  
  112.         for (XnUInt y = 0; y < depthMD.YRes(); ++y)  
  113.         {  
  114.             const XnDepthPixel* pDepth = pDepthRow;  
  115.             uchar* depthMat1u_p = depthMat1u.ptr<uchar>(y);  
  116.             for (XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth)  
  117.             {  
  118.                 if (1/**pDepth != 0*/)  
  119.                 {  
  120.                     uchar nHistValue =(uchar) pDepthHist[*pDepth];  
  121.                     depthMat1u_p[x] = nHistValue;//NiSample是将B、G两个通道都赋值生成黄色深度图  
  122.                 }  
  123.             }  
  124.             pDepthRow += depthMD.XRes();  
  125.         }  
  126.   
  127.   
  128.         //normalize(depthMat1u,depthMat1u,255,0,CV_MINMAX);  
  129.         Point maxLoc;  
  130.         double maxV;  
  131.         minMaxLoc(depthMat1u,0,&maxV,0,&maxLoc);  
  132.         Mat mask(480,640,CV_8UC1);  
  133.           
  134.         threshold(depthMat1u,mask,0.9*maxV,255,THRESH_BINARY);  
  135.         imshow("mask",mask);  
  136.   
  137.           
  138.         cvtColor(depthMat1u,depthMat3u,CV_GRAY2BGR);  
  139.         circle(depthMat3u,maxLoc,5,Scalar(0,255,0),-1);  
  140.         imshow("depthMaxloc",depthMat3u);  
  141.         key=waitKey(20);  
  142.     }  
  143.   
  144.       
  145. }  

猜你喜欢

转载自blog.csdn.net/sinat_31802439/article/details/51166481