[OpenCV|OpenNI]透過OpenCV轉換OpenNI的oni影片格式為AVI檔案

有一段時間沒寫文章了,最近真的好忙,而且又遇到了突發狀況,現在整個事Hold不住的狀態,只能盡量做到最好才行。

由於前段時間為了論文要錄製一些深度影像與彩色影像,可是Kinect出了些問題,所以就透過Xtion Pro來錄製,而要使用Xtion pro勢必得使用OpenNI的小程式來幫助,但是openNI的影片格式是Oni,所以這篇文章就是來記錄一下如何轉換,順便讓想要使用轉換的朋友可以快速了解,以及可以透過我這手邊寫的小程式直接使用 :))

前言

 


 

有一段時間沒寫文章了,最近真的好忙,而且又遇到了突發狀況,現在整個事Hold不住的狀態,只能盡量做到最好才行。

由於前段時間為了論文要錄製一些深度影像與彩色影像,可是Kinect出了些問題,所以就透過Xtion Pro來錄製,而要使用Xtion pro勢必得使用OpenNI的小程式來幫助,但是openNI的影片格式是Oni,所以這篇文章就是來記錄一下如何轉換,順便讓想要使用轉換的朋友可以快速了解,以及可以透過我這手邊寫的小程式直接使用 :))

 

OpenNI影片格式與轉換

 


 

本人使用的OpenNI版本是OpenNI2,而OpenNI2與前一版有了許多的差別,特別是架構部分,關於這些,有興趣的朋友可以到Heresy大的文章看,學習如何安裝與開發,在這邊我的程式也有參考他的文章,建議先看過他的 OpenNI2的錄製與重播 這篇

 

1.開啟錄製好的oni檔案

透過Device來開啟影片,填入檔案的路徑即可

// open a device
openni::Device devAnyDevice;
//open oni video
devAnyDevice.open( "..\\q8.oni" );  // this string is your oni file url

2.透過VideoStream類別讀取影片中的彩色畫面

把Device物件傳入,並告至 VideoStrream要讀取的是彩色畫面

openni::VideoStream streamColor;
// create color stream
if(streamColor.create( devAnyDevice, openni::SENSOR_COLOR ) == openni::STATUS_OK ){
            streamColor.start();
}

else{
            cerr << "ERROR: This device does not have color sensor" << endl;
            system("pause");
            return -1;
}

 

3.透過PlaybackControl來取得影片的一些資訊,此為取得影片的Frame長度

//Get Frame number by playbackController
openni::PlaybackControl* pController = devAnyDevice.getPlaybackControl();
int total = pController->getNumberOfFrames(streamColor);

 

4.創建OpenCV的VideoWriter物件

VideoWriter 可以用來寫入並累積Frame為一張影片,而CV_FOURCC('M', 'J', 'P', 'G') 指的是 motion-jpeg codec 編碼

OpenCV的編碼可以參考

cv::VideoWriter writer("..\\VideoTest.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25.0, cv::Size(640, 480)); 

5.撈取Frame

透過VideoFrameRef 類別,來取得VideoStream中的每一張Frame資料

// main loop, continue read
openni::VideoFrameRef frameColor;
for( int i = 0; i < total; ++ i )
{

     streamColor.readFrame( &frameColor ); //傳入frameColor 取得資料

     //convert to opencv data structure

}

 

6.轉換為OpenCV影像格式並把影像寫入至VideoWriter

//  convert data to OpenCV format
const cv::Mat mImageRGB(frameColor.getHeight(), frameColor.getWidth(), CV_8UC3, (void*)frameColor.getData() );

//  convert form RGB to BGR
cv::Mat cImageBGR;
cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );

//Write frame

writer << cImageBGR;

 

如此便能完成轉換格式了!

 

注意事項:遺失libiconv-2.dll

使用VideoWriter類別會需要libiconv-2.dll,不過貌似這個檔案在openCV2.4.8之前好像沒有,被回報是一個Bug,在2.4.8後才被包含。

 

希望這篇,可以幫助想要做轉換的朋友可以直接使用

 

程式碼範例檔在這

 

參考資料:

OpenNI 2 的資料錄製與重播

用 OpenCV 畫出 OpenNI 2 的深度、彩色影像

http://code.opencv.org/issues/3400

 


 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)

另外要轉載請附上出處 感謝