OpenNI 終於推出整個架構做了很大改變的 OpenNI 2.0 了!而這一篇,Heresy 基本上就徹底捨棄之前 OpenNI 1.x 的架構,從頭來介紹一下全新的 OpenNI 2.0 吧~雖然或多或少會提及到 OpenNI 1.x 的東西、並做比較,不過 Heresy 會盡量寫成沒接觸過 OpenNI 1.x 的人,也可以看懂。
OpenNI 簡介
OpenNI 是「Open Natural Interaction」的縮寫,大致上可以翻譯為「開放式自然操作」;而所謂的 NI 又包含哪些東西呢?OpenNI 對自然操作(Natural Interaction,以下簡稱 NI)的定義包含了「語音」、「手勢」、「身體動作」等等,基本上就是比較直覺、操作者身上不需要其他特殊裝置的操作方式了。
而 OpenNI 則是一個開放原始碼(Open Source、目前授權採用 Apache License)、跨平台(Windows, Linux)的程式開發框架(framework),他定義了一套存取、控制深度感應器的標準介面,讓開發者可以用統一的方法,來完成基於深度感應的各項操作。目前這個標準基本上是由 Microsft Kinect 和 ASUS Xtion 這兩系列感應器的核心元件(PS1080)的製造廠商、PrimeSense(官網),以及華碩(官網)等公司所組成的組織,來進行維護的。
在 OpenNI 1.x 的時候,OpenNI 的整個 framework 是透過類似 plug-in 的機制,讓開發者可以透過 OpenNI 所提供的標準介面,使用「中介軟體」(middleware)提供的人體偵測追蹤、手部追蹤等功能(詳細介紹請參考以前的介紹);不過在 OpenNI 2 的時候,為了簡化架構、增加開發的彈性,所以把這個架構移除了。
也因此,OpenNI 2.0 的架構與功能就變得相對單純,他現在只負責提供應用程式、函式庫和硬體上的溝通,讓程式開發者可以透過 OpenNI 來取得深度感應器的各項資料;至於取得資料後,要做那些處理?OpenNI 就不管了~
右圖就是 OpenNI 2.0 的架構圖。綠色的部分,就是 OpenNI 所提供的功能。雖然在其左上方,還是有一塊所謂的「Middleware Libraries」,但是實際上,這邊的 middleware library 和 OpenNI 1.x 的 middleware(主要是 PrimeSense NiTE)的意義已經大不相同了~
OpenNI 2.0 的 middleware library 基本上可以視為是一個「會透過 OpenNI 去存取感應器、進行後續處理的函式庫」,OpenNI 的架構並沒有去定義 middleware library 會有那些功能、要有那些介面;所以,在 OpenNI 2.0 的 middleware library 在開發上會相當地自由、功能也可以自由發揮~這部份的設計理念,可以參考官方的《Middleware Library Guidelines》。
但是相對的,各家 middleware 的介面也不會有一個統一的標準,開發者必須要針對個別的 middleware library 去學習它的使用方法,不像在 OpenNI 1.x 的時候,只要了解 OpenNI 的介面,就可以操作所有 middleware 了。
而在開發語言上,OpenNI 2.0 目前還在 beta 版階段,所提供的 API 目前只有 C / C (C 似乎還沒有對應的文件);不過在 OpenNI 1.x 的時候,他還有提供 .Net Framework、Java 的 wrapper,所以或許可以期待,等到 OpenNI 2.0 的正式版推出的時候,OpenNI 還是會保有他多語言的特性吧?
安裝
由於架構和功能都變單純了,所以 OpenNI 2.0 的安裝相較於 OpenNI 1.x,算是簡化了一些。基本上,只要到官方的下載頁面(連結),下載對應的 OpenNI SDK 並進行安裝就可以了;他的 32 位元和 64 位元版是獨立的,可以視需要選擇要安裝的版本。而以目前來看,OpenNI 1.x 和 OpenNI 2.0 也是可以同時安裝、使用的~
在硬體的部分,如果是使用 ASUS Xtion 系列的感應器,或是 PrimeSense 自家的感應器這類直接被 OpenNI 支援的感應器的話,OpenNI SDK 本身就包含了必要的驅動程式了(預設路徑:C:\Program Files\OpenNI2\Driver)~再加上 OpenNI 2 現在的硬體存取架構,也變成是去直接存取硬體,所以也就不像 OpenNI 1.x 的時候,還需要另外安裝驅動程式的模組了。
而如果是要使用 Microsoft Kinect for Xbox 360 或是 Kinect for Windows 感應器的話,由於 OpenNI 2.0 現在是透過微軟官方的 Kinect for Windows SDK(官網、介紹)來做支援的,所以如果是要搭配微軟 Kinect 感應器來使用 OpenNI 2.0 的話,是需要先安裝 Kinect for Windows SDK 的(目前應該是需要最新的 1.6 版)~也因為這樣,所以 OpenNI 2 Kinect 這樣的搭配,也只能用在 Kinect for Windows SDK 的系統上,也就是 WIndows Vista 以後的 Windows 作業系統了!如果是 Windows XP 或 Linux,在現階段應該都是還沒辦法使用的…
而之前的 SensorKinect 也由於是針對 OpenNI 1.x 開發的,所以在 OpenNI 2.0 的環境下,是不需要、也無法使用的。至於之後會不會有類似 SensorKinect 這樣的第三方驅動程式,讓 Kinect 可以在沒有 Kinect for Windows SDK 的環境下使用,就要再等等看了。
至於 middleware 的部分,由於在 OpenNI 2.0 的架構下,所有 middleware library 都是各自獨立的,各自的安裝方法、使用方法,也都不盡相同;所以這部分,就是要視各自的需求而決定要安裝那些東西了~Heresy 之後應該會再花些時間,來介紹一些 middleware library 吧。
最後要注意的是,舊有使用 OpenNI 1.x 的程式,如果要繼續使用的話,也是需要安裝 OpenNI 1.x 的版本的~單純安裝 OpenNI 2.0,是無法讓舊的程式使用的。
相關文件
要怎麼開始 OpenNI 2.0 的程式開發呢?在官方網站上,OpenNI 就有提供了《OpenNI Programmer’s Guide》以及《Get Started》等文件,可以供新入門的人做參考。而對於舊版 OpenNI 1.x 的用戶,也可以參考《OpenNI Migration Guide》來做學習。
而除了文件外,OpenNI 2.0 在安裝的目錄(預設會是 C:\Program Files\OpenNI2\)下,有一個 Samples 的目錄,裡面有提供一些範例,可以作為參考。
不過,Heresy 自己看了一下後,也必須說:或許是由於 OpenNI 2.0 目前還是 Beta 版(2.0.0 Build 29),所以不管是功能、文件或是範例,都沒有 OpenNI 1.x 來的齊全;而部分文件上,似乎也有一些不一致性,像是在《OpenNI Programmer’s Guide》裡有提到,OpenNI 有提供一個 getDeviceInfoList() 的函式,可以用來取得系統上的裝置列表,但是實際上應該是沒有這個函式,而是需要使用 enumerateDevices() 才對…
不過雖然還是在 beta 中,可能部分功能不是很完備,OpenNI 2.0 現在除了 PrimeSense 自己的 NiTE 2 之外,也已經有不少協力廠商,有推出各種不同功能的 middleware library 可以使用了~所以如果有需要的話,應該還是可以玩看看的~
但是,是否要在這個時間點就徹底地從 OpenNI 1.x 跳到 2.0,Heresy 是覺得可能要自己針對個別狀況評估看看了。
基本程式架構
在 OpenNI 2.0 的核心架構的部分,由於他的功能已經做了相當程度的縮減,主要的功能只剩下裝置的管理、以及原始資料的讀取(深度、紅外線、彩色影像,似乎還不支援聲音),所以在架構上,比之前的 OpenNI 1.x 簡單許多。
如果要在 C 開發 OpenNI 2.0 的程式的話,基本上就是要 include OpenNI.h 這個 header 檔;所有 OpenNI 相關的東西,基本上都是在 openni 這個 namespace 之下。和 OpenNI 1.x 使用 xn 作為 namespace,OpenNI 2 算是比較直覺的。
而在 OpenNI 2.0 的架構,如果要去存取感應器的話,主要要控制的東西,只剩下四個類別:
-
openni::OpenNI
他基本上是一個 OpenNI 整體環境控制的類別,在概念上類似 OpenNI 1.x 的 context,主要是用來做裝置(device)的取得。
由於他的所有成員函式都是 static 的,所以在使用的時候不需要實體化變數出來。 -
openni::Device
針對每一個連接到電腦上的感應器,都要用一個 Device 的物件,來做控制。而他最基本的功能,就是用來取得資料流(stream)。
-
openni::VideoStream
感應器的視訊資料流的類型。感應器的各種資料,例如深度、彩色影像,都各自對應到一個 VideoStream 的物件;在概念上,就相當於 OpenNI 1.x 的 MapGenerator。在系統內,要從 Device 來建立各自的 VideoStream。
-
openni::VideoFrameRef
透過 VideoStream 取得的個別時間點的畫面。除了影像的原始資料外,還包含了必要的 metadata。
當然,實際上 OpenNI 還有提供一些額外的類別,可以在必要的時候使用;不過在一般的狀況下,主要都是透過這四個 OpenNI 提供的 class,來可以完成資料讀取的操作。
這篇算是 OpenNI 2.0 的第一篇教學文章,就先寫到這裡了。基本上,都還是概念性的東西,等下一篇,就會真正開始講程式的撰寫的部分了~而等東西都差不多了,應該會也試著整理新的投影片,再來看看什麼時候可以來開 OpenNI 2.0 的課程吧~
好文章!对于我们初学者来说太有帮助了!支持支持~~:D
heresy 老师,欢迎在www.cnkinect.com 分享您的知识,谢谢。
请问在windows8 上安装KincetSDK1.6,OpenNI2,和Nite2后,运行示例总是出现停止工作的状态,这是怎么回事?
to Jonas
建議請先確認看看 Kinect for Windows SDK 本身的範例是否可以正確執行。
请问OpenNI1和2能够添加到MFC中去吗?
to 自溟
Heresy 沒在用 MFC,不過基本上 OpenNI 取得的資料就是一個陣列而已,要做轉換一般都是沒問題的。
请问我安装完OpenNI2了 运行NiViewer 看不到图像 但是用程序获得数据 用Opencv显示可以看到图像 请问是什么问题?
to OnePiece_h
你的看不到是怎樣狀況?
一種可能是由於 NiViewer 是用 OpenGL 來做顯示的,所以如果你的顯示卡不支援 OpenGL 的話,會可以執行,但是看不到畫面。
請確認你有安裝最新的顯示卡驅動程式,而不是使用 Windows 內建的驅動程式。
你好,請問我已經完全按照安裝順序安裝了
windows SDK, openNI2 and NiTE
可是Niviewer完全無法執行
其他的測試軟體運行都ok(SDK toolkit and samples from NiTE)
同樣的情形也在寫code的時候發生,會完全抓不到kinect device (no devices found)
我的測試環境為: win8, vs 2012, 顯示卡驅動程式也更新到最新了
請問可能是什麼原因呢?謝謝版主
to newer
不知道你執行 NiViewer 的錯誤是什麼?
而如果是自己開發程式的話,比較要注意的應該是程式執行的路徑下,要有 OpenNI.dll 和 OpenNI2 的資料夾(安裝目錄下 Redist 的檔案),這樣才能讀取到裝置驅動程式的模組。
我这个报了一堆错误用VS运行是时候,例如1>main.obj : error LNK2019: 无法解析的外部符号 __imp__oniStreamIsPropertySupported,该符号在函数 “public: bool __thiscall openni::VideoStream::isPropertySupported(int)const ” (?isPropertySupported@VideoStream@openni@@QBE_NH@Z) 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 __imp__oniStreamGetSensorInfo,该符号在函数 “private: void __thiscall openni::VideoStream::_setHandle(struct _OniStream *)” (?_setHandle@VideoStream@openni@@AAEXPAU_OniStream@@@Z) 中被引用
请问是哪配置错了吗?环境
to lsp825223208
請確定你的專案 linking 的部分有設定正確。
另外,也請確認你的 OpenNI 版本和專案建置的版本是否相同(win32/x64)。
一般的 Linking error 大多是這兩個問題造成的。
您好,heresy大神。
我目前想通过kinect第二代,获取对齐的深度图与彩色图,学习了你的几篇文章,收获很大。
但遇到一个问题,就是openni2安装后,运行NiViewer时候,找不到设备。Kinect sdk for Windows运行可以正常显示深度、彩色的。我也用VS2012编译了示例代码,Win32程序也是找不到设备。
硬件kinect第二代,系统是win8、64位,openni2.2.0.33(64位,32位都尝试过了),KinectSDK-v2.0_1409。
请问这种情况,是什么原因呢?是我还需要安装什么文件吗?
我的问题与 “newer 於 2013/10/01 14:48 下午 回應: ”应该是一样的,不知道他有没有解决这个问题呢。
谢谢博主
to 安
OpenNI 2.0 原生並不支援 Kinect for Windows v2,抓不到才是正常的。
如果真要透過 OpenNI 2 來使用的話,會需要使用分支的版本,或是自己安配置 Kinect2.dll
https://github.com/occipital/OpenNI2/tree/kinect2
谢谢你这么快回复!
我对kinect是刚刚接触,所以可能会问一些在你看来很基础的问题。
1、你说的“會需要使用分支的版本”,是指“https://github.com/occipital/OpenNI2/tree/kinect2 ”这里的吧,我已经下载了,但编译出错,是要按照readme上下载那些安装包装上再用VS2010编译就可以了吗?
2、你说的“或是自己安配置 Kinect2.dll”,请问这个是什么意思,该怎么做呢?
3、我现在主要就是想在kinect2上提取对齐的彩色图像与深度图像,有没有别的较为简单的方法呢?你之前的教程都是针对kinect1的,是吧?
heresy你好! 关于MMD支援已建立好的OpenNI2环境。我看了你写的一篇文章,有关于你基於官方網站的 DxOpenNI 1.30 做修改的編譯好的 DxOpenNI.dll,提供的下载地址已进入不了,能不能提供新的下载!!谢谢!
to 大陆某用户
檔案基本上是放在 Microsoft OneDrive 上,還可以下載的,請再試試看。
http://sdrv.ms/Zp3vhg
或者 GitHub 上也有原始碼
https://github.com/KHeresy/DxOpenNI2
to 安
1. Kinect2 的分支由於有使用到 Kinect for Windows SDK 2.0,所以需要 Visual Studio 2013 以上的版本。
2. 簡單講就是把 Kinect2.dll 放到 OpenNI2Drivers 的目錄下
3. 如果你是要用 Kinect 2 感應器的話,其實各任建議直接去使用 Kinect for Windows SDK 2.0 會比較好
http://viml.nchc.org.tw/blog/paper_info.php?CLASS_ID=1&SUB_ID=1&PAPER_ID=561
1、好的
2、kinect2.dll怎么获得呢?是否直接Kinect2.dll 放到 OpenNI2Drivers文件夹下就可以了呢?(硬件kinect第二代,系统是win8、64位,openni2.2.0.33,这是我的环境)
3、Kinect for Windows SDK 2.0 有没有获取深度图与彩色图对齐的资料呢?
to 安
2. 一個就是自己建置,不然就是要去自己找別人建置好的版本了。
3. 本站目前已經提供相關的教學文件了,請自行參考。
好的,谢谢。
我仔细看了一下,您的博文里“K4W v2 C Part 5:簡單的去背程式”涉及了对齐,Kinect for Windows SDK 2.0里面的sample的CordinateMapper也是这个。
请问一下,我pPointArray里面的有效的坐标点一个一个从pDepthPoints里面取出来,就是可以得到对齐的1920*1080的depth图像吧?这样理解对吗?
pCoordinateMapper->MapColorFrameToDepthSpace(
uDepthPointNum, pDepthPoints, uColorPointNum, pPointArray)
to 安
基本上對的。
另外,如果是 K4W SDK 的問題,建議麻煩請在對應的文章回應。
謝謝
好的,已经用微软官方的K4W SDK实现了,效果还可以。
谢谢 heresy
相當精闢的見解
請問可以引用嗎?
我是學生正在做相關的研究
to student
只要註明出處就可以囉 🙂