在OpenNI下Kinect的调用封装成类

       kinect体感开发,写了几个小的测试程序,但是在MFC的框架下使用kinect的话,那些初始化和驱动函数来回编写很麻烦,索性就把调用驱动kinect的函数模块封装成了,贴出来供大家学习和参考,我封装的类名为CkOpenNI,包括CkOpenNI.h和CkOpenNI.cpp两个文件,这个类是结合OpenCV建立,OpenCV可以方便的去做一些显示或者其他操作,因为暂时对Kinect的使用还不太充分,所以包括的成员函数并不全,会在以后的使用过程中逐渐增加的,

CkOpenNI.h代码如下:

#pragma once

#include "xntypes.h"
#include <XnCppWrapper.h>   
#include "opencv/cv.h"   
#include "opencv/highgui.h"  


using namespace std;

class CkOpenNI
{
public:
	CkOpenNI(void);
	~CkOpenNI(void);

	void Initial(void);
	void ModifyMode(XnMapOutputMode mapMode,int nXRes,int nYRes,int nFPS);
	void Start(void);
	void UpData(void);
	void  GetData(IplImage *imgDepth16u,IplImage *imgRGB8u);
	void DestoryKinect(void);

	// 产生的深度数据变量
	xn::DepthMetaData depthMD;
	// 彩色图像数据
	xn::ImageMetaData imageMD;
	// 定义输出图像属性变量
	XnMapOutputMode mapMode;
	// 状态指示器
	XnStatus status;
	//获取kinect转换后的变量
	IplImage *imgDepth16u;
	IplImage *imgRGB8u;


private:
	void CheckOpenNIError( XnStatus result, string status );

	xn::Context context;
	// 生成深度图像的变量
	xn::DepthGenerator depthGenerator;
	// 生成彩色图像变量
	xn::ImageGenerator imageGenerator;
};


CkOpenNI.cpp代码如下:
#include "CkOpenNI.h"
#include "XnCppWrapper.h"

CkOpenNI::CkOpenNI(void)
{
	status = XN_STATUS_OK;
}


/*****************初始化差错函数***********************/
void CkOpenNI::CheckOpenNIError( XnStatus result, string status )  
{   
	if( result != XN_STATUS_OK )   
		cerr << status << " Error: " << xnGetStatusString( result ) << endl;  
} 

/*****************Kinect初始化************************/
void CkOpenNI::Initial(void)
{
	status = context.Init();//初始化获生成器状态
	CheckOpenNIError(status,"initialize context");//check kinect
	context.SetGlobalMirror(true);//设置镜像

	//根据kinect默认的图像属性创建图像
	imgDepth16u = cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
	imgRGB8u = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//产生图像node
	status = imageGenerator.Create(context);
	CheckOpenNIError(status,"Create image generator");

	//产生深度node
	status = depthGenerator.Create(context);
	CheckOpenNIError(status,"Create depth generator");

	//视角矫正
	status = depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);
	CheckOpenNIError(status,"Adjust the view point");

	//return true;
}

/*******************定义输出图像的属性*********************/
void CkOpenNI::ModifyMode(XnMapOutputMode mapMode,int nXRes,int nYRes,int nFPS)
{
	//输出图像的宽
	mapMode.nXRes = nXRes;
	//输出图像的高
	mapMode.nYRes = nYRes;
	//输出图像的帧率
	mapMode.nFPS  = nFPS;
	//设置输出彩色图像属性
	status = imageGenerator.SetMapOutputMode(mapMode);
	//设置输出深度图像属性
	status = depthGenerator.SetMapOutputMode(mapMode);
}
/*****************数据开始转换***************************/
void CkOpenNI::Start(void)
{
	//开始转换
	status = context.StartGeneratingAll();
	CheckOpenNIError(status,"Start generate all ");

	//return true;
}
/*****************数据更新*******************************/
void CkOpenNI::UpData(void)
{
	//更新数据
	status = context.WaitNoneUpdateAll();  
	//获得数据
	imageGenerator.GetMetaData(imageMD);
	depthGenerator.GetMetaData(depthMD);

	//return true;
}

/***************获取数据********************************/
void  CkOpenNI::GetData(IplImage *depthShow,IplImage *imageShow)
{
	
	//将深度数据复制到imgDepth16U.imageData,图像大小为640*480,2通道
	memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);
	//使用线形变换转换数据,255/4096比例压缩,转换到0-255范围
	cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);  

	memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);  
	//色彩空间转换,将RGB存储方式转换为BGR
	cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);  
}
/****************窗口销毁和释放**************************/
void CkOpenNI::DestoryKinect(void)
{
	context.StopGeneratingAll();  
	context.Shutdown(); 
	context.Release();
	//cvReleaseImage(&imgRGB8u);
	//cvReleaseImage(&imgDepth16u);
	
}

CkOpenNI::~CkOpenNI(void)
{
}

备注:由于上一次对内存泄露没有考虑到位,导致在程序运行的过程中内存极具的增加,先将代码重新修改如上,内存泄露的原因,主要是在
void  CkOpenNI::GetData(IplImage *depthShow,IplImage *imageShow)
这个方法中,之前是的写法是这样的
void  CkOpenNI::GetData(IplImage *depthShow,IplImage *imageShow)
{
	IplImage* imgDepth16u = cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
	IplImage* imgRGB8u = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//根据kinect默认的图像属性创建图像
	imgDepth16u = cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
	imgRGB8u = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//将深度数据复制到imgDepth16U.imageData,图像大小为640*480,2通道
	memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);
	//使用线形变换转换数据,255/4096比例压缩,转换到0-255范围
	cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);  

	memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);  
	//色彩空间转换,将RGB存储方式转换为BGR
	cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR); 

	
	
}

在这个方法中,局部变量指针
IplImage* imgDepth16u = cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);

IplImage* imgRGB8u = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);


由于是调用视频数据流需要定时的更新和获得数据,在每次调用GetData方法时,这两个指针都会被定义和创建内存,而之前的内存并没用得到释放,从而造成内存的泄露,使得内存占用率极具的增高,影响项目的运行,考虑这些问题将以上方法进行修改,将
IplImage* imgDepth16u
IplImage* imgRGB8u
定义成类的成员变量而不是GetData方法的局部变量,并且在
void CkOpenNI::Initial(void)

方法中创建相应内存,从而避免了在每次更新时都进行内存创建,避免了内存泄露,修改部分的代码如下:

//获取kinect转换后的变量
	IplImage *imgDepth16u;
	IplImage *imgRGB8u;
在void CkOpenNI::Initial(void)中进行初始化:
void CkOpenNI::Initial(void)
{
	status = context.Init();//初始化获生成器状态
	CheckOpenNIError(status,"initialize context");//check kinect
	context.SetGlobalMirror(true);//设置镜像

	//根据kinect默认的图像属性创建图像
	imgDepth16u = cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
	imgRGB8u = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//产生图像node
	status = imageGenerator.Create(context);
	CheckOpenNIError(status,"Create image generator");

	//产生深度node
	status = depthGenerator.Create(context);
	CheckOpenNIError(status,"Create depth generator");

	//视角矫正
	status = depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator);
	CheckOpenNIError(status,"Adjust the view point");

	//return true;
}
void  CkOpenNI::GetData(IplImage *depthShow,IplImage *imageShow)具体实现如下:
void  CkOpenNI::GetData(IplImage *depthShow,IplImage *imageShow)
{
	
	//将深度数据复制到imgDepth16U.imageData,图像大小为640*480,2通道
	memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);
	//使用线形变换转换数据,255/4096比例压缩,转换到0-255范围
	cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);  

	memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);  
	//色彩空间转换,将RGB存储方式转换为BGR
	cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);  
}





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值