OpenNI2獲取華碩XtionProLive深度圖和彩色圖並用OpenCV顯示

masikkk發表於2014-07-02

使用OpenNI2開啟XtionProLive時有個問題,彩色圖解析度無論如何設定始終是320*240,深度圖倒是可以設成640*480,而OpenNI1.x是可以獲取640*480的彩色圖的。



彩色圖



配準到彩色圖後的深度圖



1:1融合圖



程式碼:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

#include "OpenNI.h"

using namespace openni;
using namespace cv;
using namespace std;


int main()
{
	Status rc = STATUS_OK; // OpenNI函式執行結果

	//OpenNI2圖
	VideoFrameRef oniDepthImg, oniColorImg;

	//OpenCV圖
	Mat cvDepthImg, cvBGRImg, cvFusionImg;

	//初始化OpenNI2
	rc = OpenNI::initialize();

	//開啟Kinect或Xtion裝置
	Device device;
	const char * deviceURL = openni::ANY_DEVICE;  //裝置名
	rc = device.open(deviceURL);

	//建立並開啟深度資料流
	VideoStream oniDepthStream; //深度資料流
	rc = oniDepthStream.create(device, SENSOR_DEPTH); //建立深度資料流
	if( STATUS_OK == rc )
	{
		//設定深度視訊模式
		VideoMode modeDepth;
		modeDepth.setResolution(320,240/*640,480*/); //解析度
		modeDepth.setFps(30); //幀率
		modeDepth.setPixelFormat(PIXEL_FORMAT_DEPTH_1_MM); //深度畫素格式
		oniDepthStream.setVideoMode(modeDepth);

		oniDepthStream.start(); // 開啟深度資料流
		if(STATUS_OK !=  rc)
		{
			cerr << "無法開啟深度資料流:"<<OpenNI::getExtendedError()<<endl;
			oniDepthStream.destroy();
		}
	}
	else
	{
		cerr << "無法建立深度資料流:"<<OpenNI::getExtendedError()<<endl;
	}

	//建立並開啟彩色資料流
	VideoStream oniColorStream;  //RGB資料流
	rc = oniColorStream.create(device, SENSOR_COLOR);
	if(STATUS_OK == rc)
	{
		//設定彩色視訊模式
		VideoMode modeColor;
		//不知道為什麼,彩色圖的解析度無論如何設定始終都是320*240
		modeColor.setResolution(320,240/*1280,1040*/);//解析度
		modeColor.setFps(30);//幀率
		modeColor.setPixelFormat(PIXEL_FORMAT_RGB888);

		//設定深度圖和彩色圖的配準模式
		if(device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR))
		{
			device.setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR); //深度到彩色圖配準
		}

		rc = oniColorStream.start(); //開啟彩色資料流
		if( STATUS_OK != rc )
		{
			cerr<< "無法開啟彩色資料流:"<<OpenNI::getExtendedError()<<endl;
			oniColorStream.destroy();
		}
	}
	else
	{
		cerr << "無法建立彩色資料流:"<<OpenNI::getExtendedError()<<endl;
	}

	if (!oniDepthStream.isValid() || !oniColorStream.isValid())
	{
		cerr << "彩色或深度資料流不合法"<<endl;
		OpenNI::shutdown();
		return 1;
	}

	namedWindow("depth");
	namedWindow("RGB");
	namedWindow("fusion");


	while(true)
	{
		//讀取一幀深度圖
		if( STATUS_OK == oniDepthStream.readFrame(&oniDepthImg) )
		{
			Mat cvRawImg16U(oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData());
			cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
			flip(cvDepthImg,cvDepthImg,1);//水平翻轉
			imshow("depth", cvDepthImg);
		}

		//讀取一幀彩色圖
		if( STATUS_OK == oniColorStream.readFrame(&oniColorImg) )
		{
			Mat cvRGBImg(oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData());
			cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR);
			flip(cvBGRImg,cvBGRImg,1);//水平翻轉
			imshow("RGB", cvBGRImg);
		}

		//融合圖
		cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
		addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg);
		flip(cvFusionImg,cvFusionImg,1);//水平翻轉
		imshow("fusion", cvFusionImg);

		waitKey(30);//沒有waitKey不顯示影象
	}

	destroyWindow("depth");
	destroyWindow("RGB");
	destroyWindow("fusion");

	oniDepthStream.destroy();
	oniColorStream.destroy();
	device.close();
	OpenNI::shutdown();

	return 0;
}


環境:

XtionProLive,Win7 32位,VS2010,OpenNI2.1.0,OpenCV2.4.4


原始碼下載:

http://download.csdn.net/detail/masikkk/7582485


OpenNI2.1下載:

http://download.csdn.net/detail/masikkk/7582489



參考:

Kinect+OpenNI學習筆記之2(獲取kinect的顏色影象和深度影象)

Kinect+OpenNI學習筆記之4(OpenNI獲取的影象結合OpenCV顯示)

Kinect開發教程二:OpenNI讀取深度影象與彩色影象並顯示

OpenNI2獲取華碩XtionProLive深度圖和彩色圖並用OpenCV顯示


相關文章