華碩XtionPro相似Kinect,都是體感攝像機,可捕捉深度圖和彩色圖。html
具體參數見:http://www.asus.com.cn/Multimedia/Xtion_PRO_LIVE/specifications/node
實驗設定的深度圖和彩色圖大小都是640*480,規格上說彩色圖支持更大分辨率。實測假設將彩色圖設定爲更大分辨率則會本身主動改成320*240ios
彩色圖c++
未配準時的深度圖app
配準到彩色圖後的深度圖dom
深度圖配準到彩色圖後的1:1融合圖異步
彩色圖配準到深度圖後的1:1融合圖
函數
OpenNI中提供4中數據流異步機制:tornado
(1) WaitNoneUpdateAll():不等待流的更新,這樣有可能讀出來的和上次是同一幀
(2) WaitAndUpdateAll():等待深度和彩色流都更新
(3) WaitAnyUpdateAll():隨意流有更新則返回post
(4) WaitOneUpdateAll(ProductionNode &node):等待參數指定的流更新
代碼:
#include <stdlib.h> #include <iostream> #include <string> //OpenCV c函數頭文件 #include "opencv/cv.h" #include "opencv/highgui.h" //OpenCV c++函數頭文件 #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <XnCppWrapper.h> //OpenNI的頭文件 using namespace std; using namespace cv; using namespace xn; // OpenNI的命名空間 int main() { XnStatus result = XN_STATUS_OK; //OpenNI函數的返回結果 DepthMetaData depthMD; //OpenNI深度數據 ImageMetaData imageMD; //OpenNI彩色數據 //c版本號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); //c++版本號OpenCV Mat cvDepthImg, cvBGRImg, cvFusionImg; namedWindow("depth"); namedWindow("RGB"); namedWindow("fusion"); // 建立並初始化設備上下文 Context context; result = context.Init(); if (XN_STATUS_OK != result) cerr<<"設備上下文初始化錯誤"<<endl; // 建立深度生成器和彩色生成器 DepthGenerator depthGenerator; result = depthGenerator.Create( context ); if (XN_STATUS_OK != result) cerr<<"建立深度生成器錯誤"<<endl; ImageGenerator imageGenerator; result = imageGenerator.Create( context ); if (XN_STATUS_OK != result) cerr<<"建立彩色生成器錯誤"<<endl; //經過映射模式來設置生成器參數,如分辨率、幀率 XnMapOutputMode mapMode; mapMode.nXRes = 640; mapMode.nYRes = 480; mapMode.nFPS = 30; result = depthGenerator.SetMapOutputMode( mapMode ); result = imageGenerator.SetMapOutputMode( mapMode ); // 將深度生成器的視角對齊到彩色生成器,將深度數據配準到彩色數據 depthGenerator.GetAlternativeViewPointCap().SetViewPoint( imageGenerator ); //imageGenerator.GetAlternativeViewPointCap().SetViewPoint(depthGenerator); //彩色圖配準到深度圖 // 啓動所有生成器,即啓動數據流 result = context.StartGeneratingAll(); while( true) { // 更新數據 result = context.WaitNoneUpdateAll(); if (XN_STATUS_OK == result) { //獲取一幀深度圖並轉換爲OpenCV中的圖像格式 depthGenerator.GetMetaData(depthMD); Mat cvRawImg16U(depthMD.FullYRes(), depthMD.FullXRes(), CV_16UC1, (char *)depthMD.Data() ); cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0/(depthMD.ZRes())); imshow("depth", cvDepthImg); //獲取一幀彩色圖並轉換爲OpenCV中的圖像格式 imageGenerator.GetMetaData(imageMD); Mat cvRGBImg(imageMD.FullYRes(), imageMD.FullXRes(), CV_8UC3, (char *)imageMD.Data()); cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR); imshow("RGB", cvBGRImg); //融合圖 cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR); addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg); imshow("fusion", cvFusionImg); waitKey(30); //沒有waitKey不顯示圖像 // c函數形式 //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); } } context.StopGeneratingAll(); //中止數據流 context.Shutdown(); //關閉設備上下文 destroyWindow("depth"); destroyWindow("RGB"); destroyWindow("fusion"); //cvDestroyWindow("depth"); //cvDestroyWindow("image"); //cvReleaseImage(&imgDepth16u); //cvReleaseImage(&imgRGB8u); //cvReleaseImage(&depthShow); //cvReleaseImage(&imageShow); return 0; }
環境配置:
華碩XtionProLive,Win7 32位系統,VS2010,OpenCV2.4.4,OpenNI1.5.2.23
源代碼下載:
http://download.csdn.net/detail/masikkk/7581283
OpenNI1.5 + NITE + Sensor下載:
http://download.csdn.net/detail/masikkk/7581339
參考:
Kinect+OpenNI學習筆記之2(獲取kinect的顏色圖像和深度圖像)
Kinect+OpenNI學習筆記之4(OpenNI獲取的圖像結合OpenCV顯示)