讓 OpenNI 可以透過微軟 Kinect SDK 讀取 Kinect 的資料!

針對使用 OpenNI 來進行 Kinect 的程式開發,Heresy 已經寫了好幾篇文章了;不過,基本上在一開始,Kinect 要能接到 PC 上讓 OpenNI 使用,主要就是要靠 SensorKinect(網站)這個第三方開發的驅動程式才可以。

而之前,微軟也終於推出了官方的 Beta 版 Kinect for Windows SDK(以下簡稱 MS SDK),讓大家可以用官方的 SDK、驅動程式來進行開發、使用了!雖然兩者在功能上有些差異(功能差異請參考《微軟版 Kinect SDK Beta 版推出!》一文),不過也算是有兩個不同的選擇了。

不過由於安裝了微軟版的 MS SDK 後,Kinect 的驅動程式也必須使用微軟版的,所以連帶的也代表 OpenNI 會因為沒有抓到 SensorKinect 而沒辦法使用了…

那如果想要同時使用 MS SDK 和 OpenNI 的話,該怎麼辦呢?沒關係,目前已經有網路上的強者,藉著 OpenNI 的開放架構的特性,使用 MS SDK、寫出 OpenNI 能使用的模組了!

kinect-mssdk-openni-bridge 簡介

詳細的資料可以參考 Google Group 上的《kinectsdk openni/nite at the same time》這個討論串。基本上,這個方案主要應該是「Amir」和「Tomoto」這兩位高手在進行的;Tomoto 也有將他寫好的「kinect-mssdk-openni-bridge」模組的原始碼和編譯好的執行檔,放出來讓大家可以下載使用!他的網頁是:

https://www.assembla.com/code/kinect-mssdk-openni-bridge/git/nodes/

對於一般人來說,如果沒打算去研究他的程式怎麼寫,只是想使用的話,只要下載「release」資料夾內的「kinect-mssdk-openni-bridge-0.0.zip」這個檔案(網頁)就可以了∼

目前「kinect-mssdk-openni-bridge」的版本(內部編號是 0.0.0.1),它主要是透過 MS SDK、實作了 OpenNI 的 Depth Generator、Image Generator 以及 User Generator 這三種 Production Node;這樣一來,在 OpenNI 裡只要使用這些 node,就可以不透過 SensorKinect,而是透過 MS SDK、來讀取 Kinect 的資料了!

而由於他的 User Generator 裡的 Skeleton 也是直接使用 MS SDK 的結果,所以也就不需要透過 PrimeSense 提供的 NITE 了∼如此一來,在使用上當然也就沒有必要擺出 NITE 定義的 psi 校正姿勢,而是當人進入畫面後、就直接可以抓到骨架了!不過當然相對的,功能上的限制,也就會變成是和使用 MS SDK 時一樣了(ex: 沒有關節的角度資訊、只能追蹤兩個骨架)。

另外,由於目前的 Depth Generator 和 Image Generator 似乎都和 NITE 不相容,所以在使用時、會造成其他的 Node(例如:Scene Analyzer)無法運作的狀況。這點也算是目前版本的限制之一了。

 

安裝 kinect-mssdk-openni-bridge

關於 kinect-mssdk-openni-bridge 的安裝說明,可以參考他的 readme 檔(英文版連結),不過 Heresy 在這邊還是大概說明一下。

  1. 首先,由於 Kinect for Windows SDK 本身只能用在 Windows 7 上,所以如果不是 Windows 7 的使用者,就不用再看下去了。

  2. 請將 32 位元的 OpenNI 的開發環境要架設好、並確定可以正確運作(雖然舊了點,不過如果完全沒概念的話,請參考之前的文章一文章二)。

  3. 請將微軟的 Kinect for Windows SDK 裝好,並確認官方的範例可以正確地執行。

  4. 下載「kinect-mssdk-openni-bridge-0.0.zip」這個檔案(網頁),並且解壓縮到一個想要固定存放這些檔案的位置。

  5. 在解壓縮的檔案內,會有「install.bat」,選取這的檔案後、按下滑鼠右鍵,選擇「以系統管理員身分執行」。如果執行成功的話,應該會出現類似下面的訊息:

    C:Windowssystem32>"C:Program FilesOpenNI\bin
    iReg" E:KinectForWindowskinect-mssdk-openni-bridge-0.0install.bat..\binReleasekinect-mssdk-openni-bridge.dll
    OK!

    如果最後有出現「OK!」的話,基本上就算是安裝成功了∼

  6. 要確認是否有安裝成功,請開啟一個命令提示字元,並切換目錄到「C:Program FilesOpenNIBin」、執行「niReg.exe –l」這個命令;這個命令會列出目前 OpenNI 中所有安裝的模組、和該模組所支援的 Production Node。

     Depth: Tomoto S. Washio/MSRKinectDepthGenerator/0.0.0.1
    Image: Tomoto S. Washio/MSRKinectImageGenerator/0.0.0.1
    User: Tomoto S. Washio/MSRKinectUserSkeletonGenerator/0.0.0.1

    如果有正確安裝的話,應該會找到「kinect-mssdk-openni-bridge.dll」這一項,並且會列出他的三個 node(如上);而如果有找到這樣的訊息的話,基本上應該就代表安裝成功了。

而由於這樣的安裝方法,基本上之後都會去讀這個資料夾下的「\binReleasekinect-mssdk-openni-bridge.dll」的這個檔案,所以也就代表這個資料夾不能隨便改名、或是刪除了∼如果有變動的需求的話,也請先以同樣的形式、執行「uninstall.bat」這個批次檔、以解除安裝。

 

測試與使用

要實際測試有沒有安裝成功最簡單的方法,當然還是跑程式了!而最簡單的測試,就是先去跑 OpenNI 所附的 NiViewer 了∼如果一切都安裝成功的話,應該是可以不用做額外的修改,就可以順利執行 NiViewer;而比較不一樣的是,他在執行後,他的命令提示字元視窗會出現下面的這些訊息:

Attempting to open \?USB#VID_045E&PID_02AE#A00364904743049A#{00873FDF-61A8-11D1-EF5E-00C04F2D728B}0
KinWinDeviceName = (\?USB#VID_045E&PID_02AE#A00364904743049A#{00873FDF-61A8-11D1-EF5E-00C04F2D728B}0PIPE01)
KinectCamera_OpenStreamEndpoint Opened successfully.
KinWinDeviceName = (\?USB#VID_045E&PID_02AE#A00364904743049A#{00873FDF-61A8-11D1-EF5E-00C04F2D728B}0PIPE00)
KinectCamera_OpenStreamEndpoint Opened successfully.

這算是正常的現象,只是在告訴使用者裝置開啟成功了。

在這種只有用到 Depth Generator 和 Image Generator 的狀況下,由於基本上應該只會找到一種 Node(裝了 MS SDK 後、SensorKinect 提供的 Node 就不能用了),所以在程式的部分不需要額外指定或修改。舊有的程式應該也都可以使用∼

但是如果有要用到 User Generator 的話,由於一般會同時存在兩種 User Generator(NITE 的和 kinect-mssdk-openni-bridge的),所以就必須要指定搜尋條件、告訴 OpenNI 要哪一種。而 kinect-mssdk-openni-bridge 這邊所定義的 User generator 名稱是「MSRKinectUserSkeletonGenerator」。

在程式的部分,如果是像 Heresy 之前提供的範例一樣,沒有特別去讀取 XML 設定檔的話,那就是要直接修改建立 user generator 的程式碼了∼以《透過 OpenNI / NITE 分析人體骨架》的範例來說,只要把「4. create user generator」的部分的程式,改成:

// 4. create user generator
xn::Query mQuery;
mQuery.SetName( "MSRKinectUserSkeletonGenerator" );
xn::UserGenerator mUserGenerator;
mUserGenerator.Create( mContext, &mQuery );

基本上,這部分的程式只是多加上建立 node 時的「query」條件;而在 OpenNI 裡,query 的條件就是用 xn::Query 這種特殊型別的物件來進行的。在使用上,我們只需要建立一個 xn::Query 的物件、並針對他設定條件,然後在透過 Create() 這個函式建立 Node 時,把他的 pointer 傳進去就可以了∼

OpenNI 的 xn::Query 可以針對不少條件來做設定,而以目前要使用 kinect-mssdk-openni-bridge 來說,query 的條件就只需要設定 Node 名稱是「MSRKinectUserSkeletonGenerator」就可以了;程式的寫法,就如同上面的範例、呼叫 xn::Query 本身的 SetName() 這個函式就可以了∼

而在進一步,由於 kinect-mssdk-openni-bridge 是採用 MS SDK 自動追蹤骨架的方法,所以其實本來那些為了進行骨架校正的函式、也都可以省略掉了!也就是,main() 裡面 5、6、7 這三段程式碼,以及其他所有 callback function,都是可以拿掉的!而這樣相對的,程式也就單純多了∼

 

修改 XML 設定檔

上面的修改方法,主要是要進去修改程式碼,還需要重新編譯,對於大部分的使用者都是直接使用編譯好的程式的狀況來說,其實相當不方便。所幸,以 OpenNI 的架構,他是可以透過外部的 XML 設定檔,來做一些調整的∼不過要做到這件事,程式寫法也就不一樣了。

不過由於 Heresy 之前的範例,為了簡化說明都是沒有採用讀取 XML 設定檔的方法,所以在遇到這次這樣的狀況下,反而變得相對麻煩了…所以看來要開發 OpenNI 程式比較好的方法,應該還是要讓他去讀取 XML 設定檔會比較合適;之後 Heresy 應該也還找個時間、整理一下怎麼使用 OpenNI 的 XML 設定檔吧。

是以 NITE 官方範例、或是之前介紹的 Miku Miku Dance 來說,他們都是採用讀取 XML 設定檔、來決定 OpenNI 的組態的方法;在這種情況下,就只要去修改 XML 設定檔,就可以讓程式去使用 kinect-mssdk-openni-bridge 提供的 user generator 了∼

修改的方法也相當簡單,只要找到對應的 XML 檔,並且在 UserNode 中,加入 query 的條件就可以了∼下面就是簡單的示意範例:

<OpenNI>
...
<ProductionNodes>
...
<Node type="User" name="User1">
<Query>
<Name>MSRKinectUserSkeletonGenerator</Name>
</Query>

</Node>
...
</ProductionNodes>
</OpenNI>

這裡的 <Node type="User" …>…</Node> 就是代表 User Generator 的 node,而要修改的部分,就是在他的裡面,加上名稱這項搜尋條件、也就是上面的範例裡的黃底的部分。而如果 XML 內本來沒有對於 User Generator 的描述呢?那就是要自己加一個了!

而以 NITE 的範例程式來說的話,要修改的檔案就是 NITE 目錄下的「DataSample-User.xml」這個檔案。基本上修改後的內容就是:

<OpenNI>
<Licenses>
<License vendor="PrimeSense" key="insert key here"/>
</Licenses>
<Log writeToConsole="true" writeToFile="false">
<!-- 0 - Verbose, 1 - Info, 2 - Warning, 3 - Error (default) -->
<LogLevel value="3"/>
<Masks>
<Mask name="ALL" on="false"/>
</Masks>
<Dumps>
</Dumps>
</Log>
<ProductionNodes>
<Node type="Depth">
<Configuration>
<Mirror on="true"/>
</Configuration>
</Node>
<!--<Node type="User" />-->
<Node type="User" name="User1">
<Query>
<Name>MSRKinectUserSkeletonGenerator</Name>
</Query>
</Node>

</ProductionNodes>
</OpenNI>

上面黃底的部分,是本來的 user generator 的描述,Heresy 把他註解掉了;而紫底的區塊,就是新加上的 user generator 描述、讓他去 query MSRKinectUserSkeletonGenerator 這個 node 了∼

而在這樣修改後,理論上至少 NITE 所提供的「Sample-StickFigure」,是要可以正確地在不用擺出 PSI 校正姿勢下,就追蹤到人體的骨架的。不過,由於 MS SDK 本身的限制,所以他雖然可以抓到許多個使用者,但是只有前兩個會去做骨架的追蹤,其他的使用者就沒有骨架的資料可以用了∼

如果是以 MikuMikuDance 來說的話,則是要去修改「DxOpenNI」裡面所提供的「SamplesConfig.xml」這個設定檔,在裡面加入 user generator 的描述(上面紫色的區塊)。修改之後,應該也是可以運作的∼

 

小結

基本上,「kinect-mssdk-openni-bridge」是一個非官方、讓 OpenNI 可以相容於 Microsoft 的 Kinect for Windows SDK 的第三方套件;雖然目前還不算完整,但是也還算是可以用了。而能有這樣的東西,基本上也算是 open source 的社群所賜了!

而雖然 Heresy 說可以用了,但是實際上目前版本基本上還是有一些小問題,有些功能也還不支援(最大問題是和 NITE 不相容),所以在使用上可能會出現一些怪問題的。不過這段期間,作者也還在持續地修改這個模組、讓他有更完整的功能的!所以如果有要使用的話,也請記得過段時間要來看看有沒有新版可以用∼

 

附註

  • 如果用他的 bat 檔安裝失敗的話,可以試著自己透過「niReg.exe」來註冊 kinect-mssdk-openni-bridge.dll。
  • 如果同時有安裝 32 / 64 位元的 OpenNI 的話,install.bat 會優先使用 x64 的版本來進行模組的註冊;但是實際上由於目前的版本應該還是僅能在 32 位元的應用程式上執行,所以使用上還是會有問題。這時候如果又不想把 x64 的 OpenNI 移除的話,可以看是要去修改 install.bat、或是自己執行 niReg 來註冊 kinect-mssdk-openni-bridge.dll。
  • 話說回來,OpenNI 在建立 User Generator 的時候不會自動去找列舉出所有的 node、然後找一個可以用的,其實感覺還滿笨的?希望之後的版本可以讓他自動去找一個可以用的 node 來建立,而不是直接丟回錯誤訊息。

9 thoughts on “讓 OpenNI 可以透過微軟 Kinect SDK 讀取 Kinect 的資料!”

  1. to lusile

    他有提供原始碼,可能要依此去做修改、自行建置了。

  2. Heresy,我想请问,安装了这个brige之后,可以在同一个程式中既通过openni读取user的数据,又通过ms sdk去读取user的骨骼数据吗?

  3. to Phantom
    抱歉,沒有測試過這樣來執行。
    不過,這樣做應該沒什麼意義就是了。

  4. 您好:
    想請教一個問題,目前使用Kinect Model1414,想透過Kinect取出物體的深度資訊,進而取得點雲(point cloud)資訊。

    目前在建構環境的階段,我使用MSSDK v1.6和OpenNI 32/64bit做驅動,目前遇到一個狀況,在安裝”kinect-mssdk-openni-bridge”這個套件時,出現安裝不成功。

    接著我嘗試使用Heresy的方法試圖解決問題,我也沒辦法找到niReg.exe這個檔案。
    “如果用他的 bat 檔安裝失敗的話,可以試著自己透過「niReg.exe」來註冊 kinect-mssdk-openni-bridge.dll”
    請問以上該如何操作??
    感激不盡。謝謝。

  5. to Jerry

    基本上,如果要用 OpenNI 1,個人會建議還是用 SensorKinect 比較方便。

    而如果是有需要使用 Kinect for Windows SDK 的話,可以直接使用 OpenNI 2。

    另外,沒記錯的話,niReg 這個執行檔位於 OpenNI 安裝路徑的 Bin 資料夾下。

  6. heresy:
    抱歉,筆誤,我目前安裝的是OpenNI2 32位元
    想請問我的電腦是win7 64bit, visual studio 2010
    我應該要安裝64位元的OpenNI2嗎?因為我看官方的readme.txt
    他說即便是64位元的作業系統,還是安裝32位元OpenNI2 ??

    另外我目前安裝的OpenNI2 32位元安裝路徑中沒有Bin資料夾耶
    重新安裝過一次也是一樣的結果。
    感謝指教

發佈回覆給「heresy」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。