OpenNI 2 的資料錄製與重播

| | 16 Comments| 13:25
Categories:

基本上,之前的文章裡,Heresy 已經大致把 OpenNI 2 的使用都講過了。而這一篇,則是來講一下,怎麼透過 OpenNI 2.x 的介面,來把資料錄製下來、之後再拿來使用。

基本上,OpenNI 的資料的錄製,主要是可以把原始的資料,例如深度影像、彩色影像,以 OpenNI 自己定義的檔案格式、ONI 的形式儲存下來,方便之後再使用。而使用的時候,主要是用來給 middleware library 用來分析,方便用來偵錯、開發程式,避免在開發階段要不停地走到感應器前、做出同樣的動作。

在錄製的部分,它的使用方法,大致是透過 OpenNI 2 提供的 Recorder 這個類別(官方文件),來做錄製的控制。它的使用方法,基本上如下:

  1. Recorder 在使用的時候,一樣也是先宣告出 Recorder 的物件後,再呼叫他的 create() 這個函式,來完成這個物件的建置;而在呼叫 create() 的時候,則需要把檔案名稱當作參數傳進去,如此一來,Recorder 就會把指定檔案建立出來,並把資料寫進去。

  2. 在建立完成 Recorder 的物件後,則是透過 attach() 這個函式,來指定要錄製的 VideoStream
    而除了指定 VideoStream 外,呼叫這個函式的時候,也可以決定這組資料,是否允許失真壓縮;如果允許失真壓縮的話,錄製出來的檔案大小會小很多,但是資料可能會失去一部分的準確度,所以是否要允許,就是看應用了。

  3. 接下來,就是透過 start()stop() 這兩個函式,來控制資料的錄製與否了~

  4. 最後,都結束後,呼叫 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 的人體骨架》一文裡的範例一樣,在建立 UserTrackerHandTracker 的時候,去指定使用 ONI 檔案的 Device 就可以了~

不過可能要注意的是,在使用錄製下來的 ONI 檔的時候,有的功能是無法使用的。像是 VideoMode 的變更、Image Registration Mode 的設定,以及 CoordinateConverterconvertDepthToColor(),似乎都是無法使用的。

而除了單純地使用錄製好的 ONI 檔之外,OpenNI 2 也有提供一個 PlaybackControl 的類別(官方文件),可以再使用 ONI 檔時,進行一定程度的控制;包括了是否要重播、撥放速度、總共的畫面數、跳到特定的時間…

這個物件可以透過 DevicegetPlaybackControl() 這個函式來取得,並進行操作,基本上就是:

PlaybackControl* pController = devDevice.getPlaybackControl();

而他提供的介面裡,setRepeatEnabled() 就是用來控制是否要自動重播的,setSpeed() 則是給一個浮點數、來控制撥放的速度(1.0 是正常速度);這兩者基本上都是針對整個對應到 ONI 檔案的 Device 作用的。

另外,像是 getNumberOfFrames() 則是用來針對個別的 VideoStream,取得他的所有的畫面數(時間長度)。而 seek() 的話,則是用來針對指定的 VideoStream,要求他直接跳到特定的時間點(透過 frame index 來指定);不過要注意的是,雖然是針對單一 VideoStream 做控制,但是在呼叫之後,其他 VideoStream 也會議起跳到對應的時間位置去。

16 thoughts on “OpenNI 2 的資料錄製與重播”

  1. 博主,您好,我想问你下,我想对录制好的深度视频文件使用matlab进行离线处理,但是用opencv录制的avi视频是三通道的,它是将实际距离值乘上255.0/10000,转化为0-255的,而且在读这个视频文件时,发现每个像素点的三个值不是相同的,请问是什么原因?还有就是如果用openni2录制的深度视频如何在matlab上读取呢?期待你的回信。谢谢:D:

  2. @刚蛋

    OpenNI 的深度值本身是 16bit 的,但是一般影片大多是使用 3 *8bit 來做處理,所以你如果直接用一般的錄製方法,有可能資料會被做過處理(這邊怎麼處理就是要看 OpenCV 了),假設你還要後續分析,個人建議不要這樣做。

    不然就是要去研究 OpenCV 錄製的功能,是否可以錄成單一 channel、16bit。
    或者是自己錄製成其他的格式,例如一串 matlab 可以接受的檔案,而非標準的影片檔。

  3. 博主,你好,我再问下,用openni2录制的彩色图像是三通道的吗?深度影像是单一通道,16位的吗?如果是的话,如何能将它的oni格式转换,被matlab读取呢?

  4. 博主,你好,我想问下,用openni2录制的深度视频是单通道16位的吗?彩色是三通道8位的吗?

  5. 你好,按照文章步驟想用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
    不明白其中原因,还请指教,谢谢

  6. 不是很確定,不過這個問題有可能是由於 OpenNI 和 NiTE 在特定的版本下(記得是關站前的最後版本),偶些許不相容的問題所導致的。

    問題的原因是 OpenNI 在錄製 ONI 檔時,沒有把 NiTE 所需要的屬性寫入,導致 NiTE 無法使用該檔案的資料所造成的。

    不知道是否可以提供所使用的 OpenNI 與 NiTE 版本編號、以及該 ONI 檔以供測試?

  7. 謝謝,
    openNI 版本是2.2.0.33
    Nite版本是2.21
    oni檔发送到heresy@nchc.org.tw可以麼?
    想問下你之前測試成功過的,openNI和NITE 的版本

  8. to 策淵

    電子信箱沒錯。
    另外再請教,不知道是 32 位元還是 64 位元?

    個人會建議試試看 NiTE 2 2.2.0.10 試試看。
    (最後的版本應該是 2 2.2.0.11)

  9. 已經發了,是32位元的
    我去找下2.2.0.10試試看
    謝謝

  10. to 策淵
    抱歉,有點弄錯了,應該是要測試 OpenNI 的部分。
    建議試試看用舊版的 OpenNI 來重新錄製 oni 試試看。

  11. 這個問題之前在 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

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *