OpenNI2關於不能顯示depth image問題

我們都知道OpenNI2與OpenCV可以通過Kinect獲取深度與彩色圖像。

但區別是OpenCV更強大滿足需求更多,但是隻能一幀一幀的保存。

而OpenNI2有一個videostream對象可以以視頻類型保存數據。


因爲我需要以視頻類型保存數據,所以我選擇OpenNI2來獲取深度和彩色圖像。



問題:

根據小斤(Kinect開發教程八:OpenNI2顯示深度、彩色及融合圖像)教程的代碼:

<span style="font-family:Microsoft YaHei;">/*************************
OpenNI2 Deep, Color and Fusion Image
Author: Xin Chen, 2013.2
Blog: http://blog.csdn.net/chenxin_130
*************************/

#include <stdlib.h>
#include <iostream>
#include <string>
#include "OpenNI.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
using namespace openni;

void CheckOpenNIError( Status result, string status )
{ 
	if( result != STATUS_OK ) 
		cerr << status << " Error: " << OpenNI::getExtendedError() << endl;
}

int main( int argc, char** argv )
{
	Status result = STATUS_OK;  
    
	//OpenNI2 image
	VideoFrameRef oniDepthImg;
    VideoFrameRef oniColorImg;

	//OpenCV image
	cv::Mat cvDepthImg;
	cv::Mat cvBGRImg;
	cv::Mat cvFusionImg;
	
	cv::namedWindow("depth");
	cv::namedWindow("image");
	cv::namedWindow("fusion");
	char key=0;

	//【1】
	// initialize OpenNI2
    result = OpenNI::initialize();
	CheckOpenNIError( result, "initialize context" );  

	// open device  
	Device device;
    result = device.open( openni::ANY_DEVICE );

	//【2】
	// create depth stream 
    VideoStream oniDepthStream;
    result = oniDepthStream.create( device, openni::SENSOR_DEPTH );

	//【3】
	// set depth video mode
    VideoMode modeDepth;
    modeDepth.setResolution( 640, 480 );
    modeDepth.setFps( 30 );
    modeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );
    oniDepthStream.setVideoMode(modeDepth);
	// start depth stream
    result = oniDepthStream.start();
 
	// create color stream
    VideoStream oniColorStream;
    result = oniColorStream.create( device, openni::SENSOR_COLOR );
	// set color video mode
	VideoMode modeColor;
    modeColor.setResolution( 640, 480 );
    modeColor.setFps( 30 );
    modeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );
    oniColorStream.setVideoMode( modeColor);
	
//【4】
	// set depth and color imge registration mode
	if( device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
	{
		device.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
	}
	// start color stream
    result = oniColorStream.start();  

	while( key!=27 ) 
	{  
		// read frame
		if( oniColorStream.readFrame( &oniColorImg ) == STATUS_OK )
		{
			// convert data into OpenCV type
			cv::Mat cvRGBImg( oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData() );
			cv::cvtColor( cvRGBImg, cvBGRImg, CV_RGB2BGR );
			cv::imshow( "image", cvBGRImg );
		}
  
		if( oniDepthStream.readFrame( &oniDepthImg ) == STATUS_OK )
		{
			cv::Mat cvRawImg16U( oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData() );
			cvRawImg16U.convertTo( cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
			//【5】
			// convert depth image GRAY to BGR
			cv::cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
			cv::imshow( "depth", cvDepthImg );
		}
		//【6】
		cv::addWeighted(cvBGRImg,0.5,cvFusionImg,0.5,0,cvFusionImg);
		cv::imshow( "fusion", cvFusionImg );
		key = cv::waitKey(20);
	}

	//cv destroy
	cv::destroyWindow("depth");
	cv::destroyWindow("image");
	cv::destroyWindow("fusion");

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

	return 0;
}
</span>
運行結果:


可以看到程序沒有報錯,但是卻沒有depth image。



解決辦法:

在查閱了很多資料後,在stack overflow上我看到了一個問題:Change resolution on openni2 not working

運行了代碼之後:(OniSampleUtilities.h就在OpenNI2安裝目錄下,例如我的路徑是:F:\Program Files (x86)\OpenNI2\Samples\SimpleViewer



看到他的問題是:



我猜想是不是隻運行512*424以內的格式,所以640*480便不可執行,於是我把小斤的代碼中640*480全部改爲320*240,運行:


顯示depth圖像成功!


具體的原因我也並不是很清楚,也許是OpenNI2的一個BUG吧~科科~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章