之前已經介紹過了微軟給 XBox 360 用的體感輸入裝置 Kinect 了;後來也陸續介紹了怎麼樣在 Windows 上,透過 OpenNI 來使用 Kinect 作一些應用(文章一、文章二)。
而接下來則是準備往技術面,來介紹一下,要怎麼樣用 C++ 來使用 OpenNI 了~不過這一篇,則是在進入到程式的部分前,先大概介紹一下 OpenNI 這個 Framework 的基本架構了。
首先,什麼是 OpenNI?他是「Open Natural Interaction」的縮寫,大致上可以翻譯為「開放式自然操作」;而所謂的 NI 又包含哪些東西呢?OpenNI 對自然操作(Natural Interaction,以下簡稱 NI)的定義包含了「語音」、「手勢」、「身體動作」等等,基本上就是比較直覺、操作者身上不需要其他特殊裝置的操作方式了。
OpenNI 本身則是定義了撰寫自然操作程式所需要的 API,提供一個多語言(主要是 C/C++)、跨平台的 framework;藉此提供了一個標準的介面,讓程式開發者要使用視覺、聲音相關感應器,以及對於這些資料、分析的中介軟體(middleware)時,可以更為方便。
下方則是 OpenNI 的基本架構圖:
上面的架構圖基本上分為三層,最上層是應用程式(Application),也就是我們這些程式開發者自己要撰寫的部分;最下方的一層則是硬體的部分,目前 OpenNI 支援的硬體,包含了:3D Sensor、RGB Camera、IR Camera、Audio Device 這四類。不過以目前來說,會用 OpenNI 的人,主要應該就是用 Kinect 了~而如果能有對應的驅動程式的話,其他類似的裝置,應該也是有機會可以讓 OpenNI 來存取的。
而中間這層就是 OpenNI 的部分,他除了負責和硬體的溝通外,也在自身內部預留了加上中介軟體(middleware)的空間,可以用來做手勢辨識、或是追蹤之類的處理。OpenNI 目前在 middleware 的部分,定義了下面四種元件:
由感應器取得的資料,產生身體的相關資訊,例如關節、相對位置與角度、質心等等。
追蹤手的位置。
辨識預先定義好的手勢,例如揮手。
分析場景內的資訊,例如:分離前景和背景、地板的座標軸、辨識場景內的不同物體。
目前 PrimeSense 也已經提供了一套 NITE 當作最主要的 middleware、提供上面所列的功能;而如果有更進階的需求的話,應該也可以自己寫一套相容於 OpenNI 的 middleware 來使用。當然,也希望以後會有其他軟體廠商投入這塊來開發了。
在 OpenNI 裡,他定義了所謂的「Production Node」來代表內部的基本單元,包括了硬體部分的感應器,以及 OpenNI 所提供的功能;這些 production node 分為下面三大類/層:
上面這些 Production Node 基本上都是會由不同的模組各自實作的。像是以感應器相關的部分,就是會由 OpenNI 相容的裝置提供,以目前來說,主要就是 Kinect 的驅動程式會提供這深度、影像產生的功能。而中介軟體相關的部分,則是由不同的 middleware 各自提供;不過目前的來源應該也只有 NITE 就是了。
在層級上,感應器相關的 production node 算是最底層的,由於去直接存取設備的資料,所以應用程式可以直接使用這類的 production node。而中介軟體相關的 production node 由於是靠感應器的資料來做處理的,所以他們的層級則比感應器的高一層、必須要在有感應器相關的 production node 的情況下才可以使用。
而在有了上面的這些 Production Node 後,就可以透過組合這些節點來建立所謂的「Production Chain」,並以此進行資料的處理流程。比如說要產生使用者的資料的話,就是會透過「使用者產生器」(User Generator)去存取更低層的「深度產生器」(Depth Generator);而這樣的一個節點序列,就是所謂的「Production Chain」。
OpenNI 的「Capability」機制是用來增強中介軟體和硬體裝置的彈性的;這些不同的能力都是非必要性的,各家廠商所提供的不同的中介軟體和裝置,可以自己決定要提供那些能力。而 OpenNI 則是負責定義好一些可以使用的 capability,讓程式開發者可以快速地找到符合自己需求的中介軟體或裝置。
而目前版本的 OpenNI 所支援的 capability 則如下:
讓各類型的 map generator(深度、影像、紅外線) 可以轉換到別的視角,就好像攝影機在別的位置一樣。這個功能可以快速地替不同的感應器產生的內容作對位。
讓各類型的 map generator(深度、影像、紅外線) 輸出結果可以被裁切、降低解析度;例如:VGA 可以裁切成 QVGA。這對效能的增進很有用。
讓兩個感應器產生結果同步化,藉此可以同步取得不同感應器的資料。
把產生的結果鏡像(左右顛倒)。
讓「使用者產生器(User Generator)」可以偵測出使用者特定的姿勢。
讓「使用者產生器(User Generator)」可以產生使用者的骨架資料。包含骨架關節的位置、並包含追蹤骨架位置和使用者校正的能力。
讓「深度產生器(Depth Generator)」可以針對指定的場景區域、最佳化輸出的深度影像。
讓節點可以回報他本身的錯誤狀態。
讓節點可以在 context 範圍外被鎖定。詳見《Sharing Devices between Applications and Locking Nodes》。
基本上,這些 capability 許多都是只針對特定的 Production Node 才會有的(例如 skeleton 就只有 user 這類的 node 可能有);而至於那些 Production Node 有哪些 capability 呢,就是要看更細一部的資料才會知道了~
而這篇文章,也就先寫到這裡了。當然,OpenNI 還有滿多東西,Heresy 在這就暫時先跳過了~下一篇開始,應該就是會使用 OpenNI,來寫一些簡單的範例了~
參考資料:《OpenNI User Guide》
来源:http://viml.nchc.org.tw/blog/paper_info.php?CLASS_ID=1&SUB_ID=1&PAPER_ID=214