您的位置:首页 > 运维架构

[转载]OpenNI的深度图显示

2016-04-16 10:12 411 查看
OpenNI的深度图显示有主要有两种方法:

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

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

[cpp] view
plain copy

print?





#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的直方图赋值方法:

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

代码附带深度阈值分割

[cpp] view
plain copy

print?





#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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: