讓 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:\Windows\system32>"C:\Program Files\OpenNI\bin\niReg" E:\KinectForWindows\kinect-mssdk-openni-bridge-0.0\install.bat\..\bin\Release\kinect-mssdk-openni-bridge.dll
    OK!

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

  6. 要確認是否有安裝成功,請開啟一個命令提示字元,並切換目錄到「C:\Program Files\OpenNI\Bin」、執行「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(如上);而如果有找到這樣的訊息的話,基本上應該就代表安裝成功了。

而由於這樣的安裝方法,基本上之後都會去讀這個資料夾下的「\bin\Release\kinect-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}0\PIPE01)
KinectCamera_OpenStreamEndpoint Opened successfully.
KinWinDeviceName = (\\?\USB#VID_045E&PID_02AE#A00364904743049A#{00873FDF-61A8-11D1-EF5E-00C04F2D728B}0\PIPE00)
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 目錄下的「\Data\Sample-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 來建立,而不是直接丟回錯誤訊息。

OpenNI / Kinect 相關文章目錄

對「讓 OpenNI 可以透過微軟 Kinect SDK 讀取 Kinect 的資料!」的想法

  1. 想請問這麼多種kinect的開發平台中
    只有OPEN NI可以抓到每個關節的座標然後計算尤拉角嗎?

  2. 你好,我们先前的程序开发是基于openni+ xbox360 kinect的开发环境,后来买了一个微软新出的windows版本的kinect,发现基于openni的程序不能识别出新的kinect,应该是openni驱动的问题,你有没有好的办法或者建议来处理这个问题?Thanks!

    • 請使用 unstable 版的 OpenNI、並搭配新的 SensorKinect,這樣應該就可以使用 Kinect for Windows 感應器了。

  3. 請問一下,是否一定需安裝OpenNI才能讓 MikuMikuDance讀到Kinect呢?

    如果是用Kinect SDK Sample Browser,可否辦到上述的事情?

    • Kinect SDk Sample Broswer 只是用來瀏覽 Kinect dor Windows SDK 範例程式的程式,不能用來做 Kinect 的控制。

      你如果是不希望安裝 OpenNI、而是想使用 Kinect for Windows SDK 來搭配 MMD 的話,或許可以試試看 MoggProject 的 MoggNUI。
      https://sites.google.com/site/moggproject/enghome
      不過,他是用 Kinect for Windows SDK 1.0 開發的,可能和現有的 1.5 版不相容。

  4. […] 而由於兩者的驅動程式是不同的,所以一般來說,在同一台電腦上,是沒有辦法很方便地同時使用這兩種開發環境的。不過,也由於 OpenNI 的開放性,所以實際上在 Kinect for Windows SDK 的 Beta 版出來的時候,就已經有網友針對他作封包,寫出可以在 OpenNI 下使用的模組了~而這個模組,就是 Heresy 之前在《讓 OpenNI 可以透過微軟 Kinect SDK 讀取 Kinect 的資料!》一文中介紹過的「kinect-mssdk-openni-bridge」(官網)。 […]

  5. 請教一下
    我以系統管理員身分執行install.bat 有顯示出OK的字樣
    但是我用cmd去執行niReg.exe -l 這個命令時
    他卻顯示 The environment variable could not found
    執行OpenNI的sample code 也是顯示一樣的字樣
    請問這是什麼問題呢

    謝謝

    • 這應該是 OpenNI 安裝過程有問題,導致系統環境變數不正確造成的。

      你安裝完 OpenNI 相關程式後有重開機過嗎?如果沒有的話,建議請先重開機。
      如果有的話,建議把相關程式都先移除再重新安裝試試看。

  6. 請問一下
    無法找到程式輸入點 xnGetRefContextFromNodeHandle(在動態連結程式庫 OpenNI.dll)

    這是什麼問題呢

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料