• 方法contextOpenNI: 深度图显示方法


    文章结束给大家来个程序员笑话:[M]

        OpenNI的深度图表现有重要有两种方法:

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

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

    #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);
    		
    	}
    
    }
        每日一道理
    我拽着春姑娘的衣裙,春姑娘把我带到了绿色的世界里。

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

        长处:生成的深度图层次比较显著。

        代码附带深度阈值分割

    #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;
    
    	//【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
    	// 若使用imageGenerator则深度图有一圈黑
    	depthGenerator.GetAlternativeViewPointCap().SetViewPoint( depthGenerator ); 
    
    	//【5】
    	//read data
    	result = context.StartGeneratingAll();  
    	
    	//【6】
    	result = context.WaitNoneUpdateAll();  
    
    	Mat depthMat1u(480,640,CV_8UC1);
    	Mat depthMat3u(480,640,CV_8UC3);
    	
    
    	char key=0;
    	while((key!=27) && !(result = context.WaitNoneUpdateAll()) )
    	{
    
    		//get meta data
    		depthGenerator.GetMetaData(depthMD); 
    		imageGenerator.GetMetaData(imageMD);
    
    		//直接Mat赋值操作
    		uchar *q = (uchar *) imageMD.Data();
    		Mat rgbMat1(480,640,CV_8UC3,q);
    		Mat rgbMatShow1;
    		cvtColor(rgbMat1,rgbMatShow1,CV_RGB2BGR);
    		imshow("testColorMat",rgbMatShow1);
    
    		//通过OpenNI Sample 中 NUISampleViewer 的 pDepthHist[*pDepth]操作.
    		XnDepthPixel nZRes = depthMD.ZRes();
    		float* pDepthHist = (float*)malloc(nZRes * sizeof(float));
    
    		const XnDepthPixel* pDepth = depthMD.Data();
    		xnOSMemSet(pDepthHist, 0, nZRes*sizeof(float));
    
    		unsigned int nNumberOfPoints = 0;
    		for (XnUInt y = 0; y < depthMD.YRes(); ++y)
    		{
    			for (XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth)
    			{
    				if (*pDepth != 0)
    				{
    					pDepthHist[*pDepth]++;
    					nNumberOfPoints++;
    				}
    			}
    		}
    
    		for (int nIndex=1; nIndex<nZRes; nIndex++)
    		{
    			pDepthHist[nIndex] += pDepthHist[nIndex-1];
    		}
    		
    		if (nNumberOfPoints)
    		{
    			for (int nIndex=1; nIndex<nZRes; nIndex++)
    			{
    				pDepthHist[nIndex] = (unsigned int)(256 * (1.0f - (pDepthHist[nIndex] / nNumberOfPoints)));
    			}
    		}
    
    		const XnDepthPixel* pDepthRow = depthMD.Data();
    		for (XnUInt y = 0; y < depthMD.YRes(); ++y)
    		{
    			const XnDepthPixel* pDepth = pDepthRow;
    			uchar* depthMat1u_p = depthMat1u.ptr<uchar>(y);
    			for (XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth)
    			{
    				if (1/**pDepth != 0*/)
    				{
    					uchar nHistValue =(uchar) pDepthHist[*pDepth];
    					depthMat1u_p[x] = nHistValue;//NiSample是将B、G两个通道都赋值生成黄色深度图
    				}
    			}
    			pDepthRow += depthMD.XRes();
    		}
    
    
    		//normalize(depthMat1u,depthMat1u,255,0,CV_MINMAX);
    		Point maxLoc;
    		double maxV;
    		minMaxLoc(depthMat1u,0,&maxV,0,&maxLoc);
    		Mat mask(480,640,CV_8UC1);
    		
    		threshold(depthMat1u,mask,0.9*maxV,255,THRESH_BINARY);
    		imshow("mask",mask);
    
    		
    		cvtColor(depthMat1u,depthMat3u,CV_GRAY2BGR);
    		circle(depthMat3u,maxLoc,5,Scalar(0,255,0),-1);
    		imshow("depthMaxloc",depthMat3u);
    		key=waitKey(20);
    	}
    
    	
    }

    文章结束给大家分享下程序员的一些笑话语录: 这个世界上只有10种人:懂得二进制的和不懂得二进制的。

    --------------------------------- 原创文章 By
    方法和context
    ---------------------------------

  • 相关阅读:
    邀请函|2021 云原生实战峰会,邀请您免费现场参会报名
    Game On Serverless:SAE 助力广州小迈提升微服务研发效能
    说出你和「云原生」的故事,获得年度云原生顶级盛会通行证
    巧用浏览器F12调试器定位系统前后端bug
    测试人员怎样定位bug原因
    mysql删除某个表前100条数据
    设计模式之工厂方法模式
    2021.11.19
    20211117
    JQuery插件集合
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3113100.html
Copyright © 2020-2023  润新知