基本上,之前的文章裡,Heresy 已經大致把 OpenNI 2 的使用都講過了。而這一篇,則是來講一下,怎麼透過 OpenNI 2.x 的介面,來把資料錄製下來、之後再拿來使用。
基本上,OpenNI 的資料的錄製,主要是可以把原始的資料,例如深度影像、彩色影像,以 OpenNI 自己定義的檔案格式、ONI 的形式儲存下來,方便之後再使用。而使用的時候,主要是用來給 middleware library 用來分析,方便用來偵錯、開發程式,避免在開發階段要不停地走到感應器前、做出同樣的動作。
在錄製的部分,它的使用方法,大致是透過 OpenNI 2 提供的 Recorder 這個類別(官方文件),來做錄製的控制。它的使用方法,基本上如下:
-
Recorder 在使用的時候,一樣也是先宣告出 Recorder 的物件後,再呼叫他的 create() 這個函式,來完成這個物件的建置;而在呼叫 create() 的時候,則需要把檔案名稱當作參數傳進去,如此一來,Recorder 就會把指定檔案建立出來,並把資料寫進去。
-
在建立完成 Recorder 的物件後,則是透過 attach() 這個函式,來指定要錄製的 VideoStream。
而除了指定 VideoStream 外,呼叫這個函式的時候,也可以決定這組資料,是否允許失真壓縮;如果允許失真壓縮的話,錄製出來的檔案大小會小很多,但是資料可能會失去一部分的準確度,所以是否要允許,就是看應用了。 -
接下來,就是透過 start() 和 stop() 這兩個函式,來控制資料的錄製與否了~
-
最後,都結束後,呼叫 destory() 把自己摧毀掉。
下面就算是一段比較完整的範例:
// Initial OpenNI
OpenNI::initialize();
 
// Open Device
Device devDevice;
devDevice.open( ANY_DEVICE );
 
// Create depth stream
VideoStream vsDepth;
vsDepth.create( devDevice, SENSOR_DEPTH );
 
// create recorder
Recorder recRecorder;
recRecorder.create( "d:\\test.oni" );
recRecorder.attach( vsDepth );
 
// start
vsDepth.start();
recRecorder.start();
 
// main loop
//....
如此一來,程式就會把深度影像錄到 d:\test.oni 這個檔案裡了~
接下來,要怎麼使用錄製好的 ONI 檔案呢?基本上,OpenNI 2 的 Device 在透過 open() 這個函式來開啟裝置的時候,是需要透過給一個 URI 的字串,來決定要開啟哪個裝置的;而在一般的狀況下,是可以給定義好的 ANY_DEVICE,來讓 OpenNI 去找任何一個可以用來使用的實體裝置。
如果要開啟錄製好的 ONI 檔的話,也相當簡單,只要把 ANY_DEVICE 改成檔案名稱傳進 open() 就可以了~而之後,這個 Device 就可以和一般使用一樣進行操作了~下面就是一個簡單的例子:
Device devDevice;
devDevice.open( "d:\\test.oni" );
而如果想讓 NiTE 2 去使用錄製下來的資料的話,也就只需要像《使用 OpenCV 畫出 NiTE2 的人體骨架》一文裡的範例一樣,在建立 UserTracker 或 HandTracker 的時候,去指定使用 ONI 檔案的 Device 就可以了~
不過可能要注意的是,在使用錄製下來的 ONI 檔的時候,有的功能是無法使用的。像是 VideoMode 的變更、Image Registration Mode 的設定,以及 CoordinateConverter 的 convertDepthToColor(),似乎都是無法使用的。
而除了單純地使用錄製好的 ONI 檔之外,OpenNI 2 也有提供一個 PlaybackControl 的類別(官方文件),可以再使用 ONI 檔時,進行一定程度的控制;包括了是否要重播、撥放速度、總共的畫面數、跳到特定的時間…
這個物件可以透過 Device 的 getPlaybackControl() 這個函式來取得,並進行操作,基本上就是:
PlaybackControl* pController = devDevice.getPlaybackControl();
而他提供的介面裡,setRepeatEnabled() 就是用來控制是否要自動重播的,setSpeed() 則是給一個浮點數、來控制撥放的速度(1.0 是正常速度);這兩者基本上都是針對整個對應到 ONI 檔案的 Device 作用的。
另外,像是 getNumberOfFrames() 則是用來針對個別的 VideoStream,取得他的所有的畫面數(時間長度)。而 seek() 的話,則是用來針對指定的 VideoStream,要求他直接跳到特定的時間點(透過 frame index 來指定);不過要注意的是,雖然是針對單一 VideoStream 做控制,但是在呼叫之後,其他 VideoStream 也會議起跳到對應的時間位置去。
博主,您好,我想问你下,我想对录制好的深度视频文件使用matlab进行离线处理,但是用opencv录制的avi视频是三通道的,它是将实际距离值乘上255.0/10000,转化为0-255的,而且在读这个视频文件时,发现每个像素点的三个值不是相同的,请问是什么原因?还有就是如果用openni2录制的深度视频如何在matlab上读取呢?期待你的回信。谢谢:D:
@刚蛋
OpenNI 的深度值本身是 16bit 的,但是一般影片大多是使用 3 *8bit 來做處理,所以你如果直接用一般的錄製方法,有可能資料會被做過處理(這邊怎麼處理就是要看 OpenCV 了),假設你還要後續分析,個人建議不要這樣做。
不然就是要去研究 OpenCV 錄製的功能,是否可以錄成單一 channel、16bit。
或者是自己錄製成其他的格式,例如一串 matlab 可以接受的檔案,而非標準的影片檔。
博主,你好,我再问下,用openni2录制的彩色图像是三通道的吗?深度影像是单一通道,16位的吗?如果是的话,如何能将它的oni格式转换,被matlab读取呢?
@刚蛋
ONI 的確是可以錄製原始的資料,不過因為他是 OpenNI 自己定義的格式,所以 matlab 應該沒辦法直接讀取。
要用的話,就是要看有沒有人針對 matlab 寫過了。
example: http://www.mathworks.com/matlabcentral/fileexchange/30242-kinect-matlab
博主,你好,我想问下,用openni2录制的深度视频是单通道16位的吗?彩色是三通道8位的吗?
@刚蛋
在沒有特別修改 VideoMode 的情況下,是的。
你好,按照文章步驟想用nite處理錄好的oni格式的視頻
程式代碼如下
Device dev;
dev.open(“d:\test.oni”);
VideoStream vsDepth;
vsDepth.create( dev, SENSOR_DEPTH );
vsDepth.start();
nite::NiTE::initialize();
nite::UserTracker mUserTracker;
mUserTracker.create(&dev);
最後一句mUserTracker.create(&dev); 會引起 memory access violation error
不明白其中原因,还请指教,谢谢
不是很確定,不過這個問題有可能是由於 OpenNI 和 NiTE 在特定的版本下(記得是關站前的最後版本),偶些許不相容的問題所導致的。
問題的原因是 OpenNI 在錄製 ONI 檔時,沒有把 NiTE 所需要的屬性寫入,導致 NiTE 無法使用該檔案的資料所造成的。
不知道是否可以提供所使用的 OpenNI 與 NiTE 版本編號、以及該 ONI 檔以供測試?
謝謝,
openNI 版本是2.2.0.33
Nite版本是2.21
oni檔发送到heresy@nchc.org.tw可以麼?
想問下你之前測試成功過的,openNI和NITE 的版本
to 策淵
電子信箱沒錯。
另外再請教,不知道是 32 位元還是 64 位元?
個人會建議試試看 NiTE 2 2.2.0.10 試試看。
(最後的版本應該是 2 2.2.0.11)
已經發了,是32位元的
我去找下2.2.0.10試試看
謝謝
不好意思,NITE版本確實弄錯了
我的是2.2.0.11
重新裝了NiTE 2 2.2.0.10
測試出現同樣的問題
to 策淵
抱歉,有點弄錯了,應該是要測試 OpenNI 的部分。
建議試試看用舊版的 OpenNI 來重新錄製 oni 試試看。
您建議哪個版本的openNI?
這個問題之前在 OpenNI 官方論壇也有討論過。不過很遺憾的是,目前官網關了,相關資料也找不到了。
所以 Heresy 現在也無法確認相關的版本資訊…
個人會建議試試看換個 OpenNI 的版本來錄看看。
或許可以考慮直接自己去建置最新版的 OpenNI 2.3
https://github.com/OpenNI/OpenNI2/tree/develop
這個版本對於 Kinect 的支援比較完整。
或者,網路上看到有人說把 NiTE 降到 2.0 可以解決。
http://stackoverflow.com/questions/21394886/nite2usertracker-crashes-when-reading-from-oni-files