讓 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 for Windows SDK
    但是之後把他移除了
    執行NiViewer還是顯示open failed:file not found
    至於BETA版還無下載
    不過現在已經想單純的用kinect就好了

    • 麻煩確認一下:
      1. 在 OpenNI 環境下,裝置管理員裡是否有正確抓到 PrimeSense 下的三個 Kinect 裝置(Camera、Motor、Auto)?

      2. 請確認一下你是執行哪裡的 NiViewer?
      理論上,NiViewer 的執行檔應該會在 C:\Program Files\OpenNI\Samples\Bin\Release
      而同時,在 C:\Program Files\OpenNI\Data 裡應該要有 SamplesConfig.xml,這樣才能正確執行。

      另外,麻煩同一個主題請回在同一串回應中,以方便管理,謝謝

  2. Heresy:
    其實小弟一開始就是載新版的
    而且Windows SDK也是可以使用的..
    很奇妙的是還沒裝kinect-mssdk-openni-bridge-1.3.3.6之前
    先用了sensorkinect
    打開NiViewer.exe也會出現open failed:file not find
    能否請大大幫解答

    • 要使用單純 OpenNI 環境的話,Kinect 必須使用 SensorKinect 的驅動程式。
      如果你有安裝 Kinect for Windows SDK 的話,有可能驅動程式會是使用 Microsoft 官方的,這時候需要手動強制修改驅動程式才行。

      而 Kinect for Windows 的部分,你是使用哪個版本?前面已經有提過了,kinect-mssdk-openni-bridge 很有可能得用舊版的 Kinect for Windows SDK 才行,不知道是否有試過?

  3. 想問Heresy一按下niReg.exe –l這個指令後
    跑了一小斷出現"遺失MSR Kinect NUI.dll"是什麼原因呢?
    是因為OPENNI本身沒裝好嗎@@?

  4. 版大你好,
    我在將install.bat執行完之後是有顯示OK的,
    接下來我在檢查的時候先輸入cd C:\Program Files\OpenNI\Bin,
    把目錄轉到C:\Program Files\OpenNI\Bin,
    接下來可能是我不會執行niReg.exe –l,
    所以我出現的是Failed:File not found!
    是我在執行niReg.exe –l 出錯了嗎?
    請問該怎麼正確執行這一步~

    我去測試 NiViewer的時候,
    畫面跟版大的類似,
    不過後來卻發生錯誤。

    不過我執行完install.bat後是有顯示OK的,
    所以不是應該可以了嗎~

    還有請問大大同時安裝openNI和MS SDK後,
    還可以將Kinect當虛擬攝影機用嗎?
    謝謝

    • 1. 他有推出新版本了,建議請改用新版本。
      https://www.assembla.com/code/kinect-mssdk-openni-bridge/git/nodes/release/kinect-mssdk-openni-bridge-1.3.3.6.zip

      2. 如果是 64 位元的作業系統的話,需要執行 niReg64.exe;也請先確認該資料夾下是否有對應的檔案。

      3. 雖然理論上它可以透過 OpenNI 來存取 Kinect for Windows SDK 的資料,理論上大部分的 OpenNI 程式應該都可以支援。但是不見得可以完全、完美的支援。畢竟,這東西目前也只算是第三方的程式,也還只是 beta 版。

      而至於你的 NiViewer 出問題,不知道是怎樣的錯誤?

      • 不好意思板大,
        我用了新版的之後,
        一開始開機 NiViewer 可以執行,
        但是過了一陣子後居然又不行…,
        然後像NiUserTracker這種會追蹤到人的,
        則是一直都無法執行,
        會不會是跟我沒有 “用 Sensor「\SampleXMLs\NITE\Data\」目錄內的所有 XML 檔案(三個),取代掉 NITE「\Data\」目錄內的 XML 檔" 有關?
        因為我找不到 \SampleXMLs\NITE\Data\ 這個路徑 所以就沒用了。

        還有請問大大同時安裝openNI和MS SDK後,
        還可以將Kinect當虛擬攝影機用嗎?
        謝謝

        • 安裝時的 XML 在新版已經不用取代了。

          不過,這篇也有提到了,如果你要使用 kinect-mssdk-openni-bridge 的話,XML 還是要修改,才能使用正確的 User Generator 的。請確認你有正確地修改 NITE 的 XML 設定檔。

          至於是否可以在安裝 kinect-mssdk-openni-bridge 的情況下,把 Kinect 當虛擬攝影機?Heresy 沒有試過,只能說理論上可以。

          不過,建議你還是用單純的環境來做測試,會比較好一點。

      • 補充一下,
        我後來無法執行 NiViewer 是出現下面的訊息。
        (null)(HRESULT=8004022d):NuiInitialize(m_nInitFlags)
        m_pReader->Start():Error!
        Open failed:Erroe!
        Press any key to continue…

        • NuiInitialize 這個函式應該是 Microsoft 的 SDK 的,所以這邊是死在 Microsoft 的 SDK 那端。
          建議你先試試看你的 Microsoft Kinect for Windows SDK 是否可以正常運作,再來試透過 OpenNI 來存取 Kinect。

  5. 簡單來說我就是希望可以抓到微軟定義20個點的3D座標但是又可以不需要PSI校正….不好意思因為技術層面比較弱問題有點煩……謝謝你@@

  6. 不好意思請問一下…因為我最近要拿這台來做動作分析….所以需要3D座標…我爬文看到OpenNI 可以將二為座標轉為3D座標….但是我又不希望要做PSI校正…..請問透過這個連接可以做得到嗎….那麼抓到的點一樣會是20個嗎????拜託我真的很希望不需要校正前置動作又可以拿到3D坐標@@

    • 如果只是這樣的需求的話,你應該可以直接使用微軟版的 SDK,應該就符合你的需求了。
      並不一定要用 OpenNI。

  7. Heresy大大請問一下喔,
    如果這個kinect-mssdk-openni-bridge有辦法臻於完美的狀況來說,
    是用MS的SDK的所有能力,然後用OpenNI撰寫程式嗎?
    感覺用WinAPI真的有點綁手綁腳的,也不知道如何下手(搔頭

    • 基本上,由於這是非官方的東西,所以很難保證會完整到什麼程度。
      而就算一切都完整了,它的功能應該也只會是兩者的交集,也就是:
      1. NITE 做得到、但是 MS SDK 做不到的,透過 kinect-mssdk-openni-bridge 應該就做不到(除非有人補)
      2. MS SDK 做得到的,但是 OpenNI 沒定義的,那透過 kinect-mssdk-openni-bridge 還是沒辦法用(例如 Kinect 的馬達操作、聲音擷取)

      Heresy 只能說,如果不想學 winapi,就放棄它吧~
      看看要從 C# 著手來寫 MS SDK、還是就直接用 OpenNI 寫吧。

  8. 我比較好奇這樣子做的優、缺點是什麼?
    在程式撰寫的部分會有什麼影響??
    還是只是單純地讓openNI用Kinect SDK的驅動
    其他程式撰寫的部分還是以openNI為主嗎?

    • 基本上,文章裡已經有提了,程式撰寫的部分除了要去 query 特定的 node 外,其他都就都是標準的 OpenNI 語法。
      以目前的版本來說,除了功能性會被 MS 的 Kinect SDK 限制綁住外,最大的缺點是功能不完整、和 NITE 不相容吧~

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.