OpenCV--鼠标响应Kinect彩色图像显示深度信息

来源:互联网 发布:努比亚z11mini网络 编辑:程序博客网 时间:2024/04/20 04:42
#include<cv.h>#include<highgui.h>#include<XnCppWrapper.h>#include<iostream>using namespace std;struct CvKinectImage{IplImage* depth;IplImage* image;IplImage* imageShow;IplImage* depthShow;CvPoint point;       unsigned short pointData; };void check(XnStatus result,string step){if(result != XN_STATUS_OK)cout<<step<<" error: "<<xnGetStatusString(result)<<endl;return;}// callback functionvoid cvMouseCallback(int mouseEvent,int x,int y,int flags,void* param){CvKinectImage* kinectImage = (CvKinectImage*)param;if(mouseEvent == CV_EVENT_MOUSEMOVE){kinectImage->point = cvPoint(x,y);//kinectImage->pointData = CV_IMAGE_ELEM(kinectImage->depth,unsigned short,y,x);}return;}int main(int argc,char* argv[]){// initialize contextXnStatus isError = XN_STATUS_OK;xn::Context context;isError = context.Init();check(isError,"initialize context");// create depth generatorxn::DepthGenerator depthGen;isError = depthGen.Create(context);check(isError,"create depth generator");// create image generatorxn::ImageGenerator imageGen;isError = imageGen.Create(context);check(isError,"create image generator");// set map output modeXnMapOutputMode mode;mode.nXRes = 640;mode.nYRes = 480;mode.nFPS = 30;isError = depthGen.SetMapOutputMode(mode);check(isError,"set depth output mode");isError = imageGen.SetMapOutputMode(mode);check(isError,"set image output mode");// correct viewpointimageGen.GetAlternativeViewPointCap().SetViewPoint(depthGen);// start generating image and depth dataisError = context.StartGeneratingAll();check(isError,"start generating data");// define and initialize a CvKinectImage structCvKinectImage kinectImage;kinectImage.depth = cvCreateImage(cvSize(640,480),IPL_DEPTH_16S,1);kinectImage.image = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);kinectImage.depthShow = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);kinectImage.imageShow = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);kinectImage.point = cvPoint(0,0);cvNamedWindow("depth",CV_WINDOW_AUTOSIZE);cvNamedWindow("image",CV_WINDOW_AUTOSIZE);// register the callback functioncvSetMouseCallback("image",cvMouseCallback,&kinectImage);// define meta dataxn::DepthMetaData depthMD;xn::ImageMetaData imageMD;// set environment to put text into an imageCvFont font;cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0,1.0);char dataString[80];while(context.WaitAndUpdateAll() == XN_STATUS_OK){// get meta datadepthGen.GetMetaData(depthMD);imageGen.GetMetaData(imageMD);// copy meta data to the related struct membersmemcpy(kinectImage.depth->imageData,depthMD.Data(),640*480*2);memcpy(kinectImage.image->imageData,imageMD.Data(),640*480*3);// convert scale and color formatcvConvertScale(kinectImage.depth,kinectImage.depthShow,255.0/4096.0);cvCvtColor(kinectImage.image,kinectImage.imageShow,CV_RGB2BGR);// get depth data and put it to the imagekinectImage.pointData = CV_IMAGE_ELEM(kinectImage.depth,unsigned short,kinectImage.point.y,kinectImage.point.x);sprintf(dataString,"(%d,%d):%dmm",kinectImage.point.x,kinectImage.point.y,kinectImage.pointData);cvPutText(kinectImage.imageShow,dataString,kinectImage.point,&font,CV_RGB(0,255,0));// show imagecvShowImage("depth",kinectImage.depthShow);cvShowImage("image",kinectImage.imageShow);if(cvWaitKey(10) == 27) break;}// set memory freecvDestroyWindow("depth");cvDestroyWindow("image");cvReleaseImage(&kinectImage.depth);cvReleaseImage(&kinectImage.image);cvReleaseImage(&kinectImage.depthShow);cvReleaseImage(&kinectImage.imageShow);// shut downcontext.StopGeneratingAll();context.Shutdown();return 0;}

回调函数只是更新了鼠标所指示的点的坐标,将深度数据打印在彩色图像上的操作在while语句中完成。深度数据的更新不能在回调函数中进行,必须在while中完成。因为如果深度数据在回调函数中更新,则当鼠标移动后停止在彩色图像显示窗口时,回调函数不会执行,深度数据不会更新,但是深度图像和彩色图像都已更新,旧数据不能反映更新后的深度图像中的数据,故而出错。

顺便说一句,在初始化CvKinectImage结构时,必须初始化其中的point成员,否则编译有误。因为为point成员赋值是在回调函数中完成的,但是回调函数只是在鼠标移动时才会触发。如果不初始化kinectImage.point,则可能在没有初始化的时候while循环中已经使用了它的值。

http://blog.csdn.net/chenli2010/article/details/6897161

原创粉丝点击