[转载]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);
}
}
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);
}
}
相关文章推荐
- 架设NFS服务器
- liunx bash 学习记录1
- Linux初始root密码设置
- linux下vim编辑器详解
- Linux进程调度
- Linux快捷登录二 sshpass命令
- ti processor sdk linux am335x evm /bin/commom.sh hacking
- Exception sending context initialized event to listener instance of class org.apache.tomcat.websocke
- 图解服务化架构演进
- Linux中exec命令相关
- Linux学习之CentOS(一)--CentOS7环境搭建
- 解决Tomcat部署Maven异常:Deployment is out of date due to changes in the underlying project contents
- JVM调优之Tomcat启动参数配置及详解(一)
- //mywebshell.php
- 架构高性能网站秘笈(六)——构建数据缓冲区
- 再来说说Linux文件权限那些事儿
- 架构高性能网站秘笈(六)——负载均衡
- 架构高性能网站秘笈(五)——Web组件分离
- 架构高性能网站秘笈(四)——反向代理缓存
- 架构高性能网站秘笈(三)——浏览器缓存