NiTE(官網)是 PrimeSense 針對 OpenNI 這個深度感應器程式開發 Framework 所推出的一套 middleware,他主要的功能,包括了使用者的偵測、人體骨架的分析與追蹤、手部的追蹤、姿勢手勢辨識等等。
在 OpenNI 1.x 的時候,雖然 OpenNI 是提供了一個開放的框架,讓開發者自行根據規格來實作各自的 middleware;但是實際上,到最後還是只有 NiTE 這一套而已…或許是這個原因,在 OpenNI 2 的新架構下,OpenNI 的框架不再去定義 middleware 的介面和功能,而是把本來屬於 plug-in 的 middleware,改成讓使用者直接去使用的函式庫的形式。
在這種模式下,OpenNI 2 的 middleware library 的功能變得更自由,不再被 OpenNI 定義的介面綁死,在開發上也更彈性了~而在 OpenNI 2 發布的同時,也就已經有不少由其他開發者提供的 middleware library 跟著一起上線了(連結)~
而當然,PrimeSense 還是有持續維護他們的 NiTE、針對 OpenNI 2 推出新的 NiTE 2(連結),繼續提供本來就有的手部、骨架追蹤,以及姿勢和手勢的偵測。不過由於整個架構的改變,使用方法和 OpenNI 1.x 的時候也有很大的差別;這邊,就大概來講一下怎麼在 OpenNI 2 的架構下,使用 NiTE 2 吧~
專案設定
首先,在專案設定的部分,要設定的項目和 OpenNI 2 基本上是相同的,包括了:
-
「C/C++」的「Gerenal」(一般)裡的「Additional Include Directories」(其他 Include 目錄)要加上 $(NITE2_INCLUDE) 或 $(NITE2_INCLUDE64)。
-
「Linker」(連結器)的「Gerenal」(一般)裡的「Additional Library Directories」(其他程式庫目錄)要加上 $(NITE2_LIB) 或 $(NITE2_LIB64)。
- 「Linker」(連結器)的「Input」(輸入)裡的「Additional Dependencies」(其他相依性)要加上 NiTE2.lib。
比較完整的圖文設定說明,請參考《OpenNI 2 基本程式範例》一文,基本上,只是修改要甜的東西、把 OpenNI2 改成 NITE2 而已。不過另外要注意的就是,由於 NiTE 會使用到 OpenNI,所以本來 OpenNI 2 的設定也是需要加上去的~
再來,就是和 OpenNI 2 一樣,在程式執行的時候,會需要使用到 NiTE 的 Redist 目錄(預設是在 C:\Program Files\PrimeSense\NiTE2\Redist)下的檔案,所以也是一樣,需要讓程式找到的這些檔案。也因為會同時需要 OpenNI 2 和 NiTE 2 兩個函式庫的 Redist 資料夾,Heresy 會建議把這兩個資料夾的檔案,複製出來、放到同一個資料夾,然後把這個資料夾設定成為這個專案的「Working Directory」(工作路徑),這樣程式才可以正常執行;如果沒有處理好的話,可能就會出現類似下面的錯誤訊息:
Failed to initialize OpenNI Found no files matching '.\OpenNI2\Drivers\*.dll'
Could not find data file .\NiTE2/s.dat current working directory = C:\Program Files\OpenNI2\Redist
如果遇到「遺失 dll」的錯誤訊息,或是執行時有上面的錯誤訊息的話,請確認程式工作路徑下,要有下列的檔案:NiTE.ini、NiTE2.dll、OpenNI.ini、OpenNI2.dll、PS1080.ini ,以及 NiTE2 和 OpenNI2 這兩個資料夾。這些檔案,基本上都是在 OpenNI 和 NiTE 的 Redist 資料夾裡面的。
基本架構
NiTE 2 的架構、和使用概念,基本上都和 OpenNI 2(請參考《OpenNI 2 簡介》)非常地相似,所以如果已經知道 OpenNI 2 的程式怎麼寫,應該很容易就可以上手。比較大略性的來看,會使用來控制的類別,主要包括了:
-
nite::NiTE
NiTE 2 的整體環境控制的類別,基本上是用來控制 NiTE 的初始化和停止。
和 openni::OpenNI 一樣,他所有的函示都是 static 的,使用時不需要實體化變數出來。 -
nite::UserTracker
用來追蹤使用者的類別,包括了使用者的管理,以及骨架追蹤、姿勢偵測等功能;性質和 OpenNI 1.x 的 User Generator 類似。
讀取出來的資料類型,是 nite::UserTrackerFrameRef。 -
nite::HandTracker
用來進行手部追蹤的類別,除了追蹤手部位置外,也包含了手勢的偵測。基本上算是把 OpenNI 1.x 的 Hands Generator 和 Gesture Generator 的功能加在一起。
讀取出來的資料類型,是 nite::HandTrackerFrameRef。
基本上,NiTE 只又在程式開始、結束的時候需要用到,中間基本上是用不到的;使用概念和 openni::OpenNI 一樣。而 UserTracker 和 HandTracker 的使用概念,則也和 openni::VideoStream 相似。更完整的說明,可以參考官方的文件,檔案預設是在 C:\Program Files\PrimeSense\NiTE2\Documentation。
基本使用
NiTE 2 雖然需要 OpenNI 2 的功能(NiTE.h 就會去使用 OpenNI.h),但是實際上,如果只是單純要使用 NiTE 所提供的功能的話,在程式碼裡面,是可以完全不出現 OpenNI 的東西的~他最基本的使用流程,大致如下:
-
include NiTE.h 這個 header 檔,之後 NiTE C++ API 的東西,都會在 nite 這個 namespace 下。
-
呼叫 nite::NiTE::initialize() 來進行整個 NiTE 環境的初始化。
-
宣告出一個 NiTE 的物件,如果是要做使用者/骨架的追蹤的話,就是使用 nite::UserTracker,如果是要做手部相關的處理的話,則是用 nite::HandTracker。
之後再透過他所提供的 create() 函式,來完成 NiTE Tracker 的建立。
-
create() 這個函式有一個參數,可以指定要使用哪一個 openni::Device,如果不指定的話,NiTE 會自己去找一個可以用的,自己開啟來使用。
-
-
和 OpenNI 的 VideoStream 不同,NiTE 2 提供的兩個 Tracker,都沒有 start() 和 stop() 的函示可以用來控制開始和結束。所以要使用的話,就是直接進入主迴圈,透過 readFrame() 這個函式,來取得對應的 frame reference(nite::UserTrackerFrameRef 或 nite::HandTrackerFrameRef);而之後會用到的資料,基本上都在讀取到的 frame reference 中。
-
程式結束時,呼叫 Tracker 的 destory() 函式,把 Track 關掉。
-
最後,呼叫 nite::NiTE::shutdown(),關閉整個 NiTE 環境。
簡單的範例
上面算是概要性的講了一下 NiTE 2 要怎麼使用,接下來,則是一個極簡單的 NiTE 的範例。在這個範例程式裡面,基本上是直接去使用 NiTE2 的 UserTracker 來進行使用者的追蹤,完全不會直接使用到 OpenNI 的介面。
// STL Header #include <iostream> // 1. include NiTE Header #include <NiTE.h> // using namespace using namespace std; int main( int argc, char** argv ) { // 2. initialize NiTE nite::NiTE::initialize(); // 3. create user tracker nite::UserTracker mUserTracker; mUserTracker.create(); nite::UserTrackerFrameRef mUserFrame; for( int i = 0; i < 300; ++ i ) { // 4. get user frame mUserTracker.readFrame( &mUserFrame ); // 5. get users' data const nite::Array<nite::UserData>& aUsers = mUserFrame.getUsers(); for( int i = 0; i < aUsers.getSize(); ++ i ) { const nite::UserData& rUser = aUsers[i]; if( rUser.isNew() ) cout << "New User [" << rUser.getId() << "] found." << endl; if( rUser.isLost() ) cout << "User [" << rUser.getId() << "] lost." << endl; } } nite::NiTE::shutdown(); return 0; }
可以看到,整個流程基本上和 OpenNI 2 非常的相近,最大的差別,就在於 UserTracker 讀取到的資料,是 UserTrackerFrameRef 的形式,資料的存取方法和 OpenNI 的 VideoStream 不同而已。
像在個範例面,Heresy 就是先透過 UserTrackerFrameRef 的 getUsers() 這個函式,來取得使用者的列表;這邊的列表,會是一個陣列 nite::UserData 的陣列(和 OpenNI 2 一樣,NiTE 2 又自己定義一個 Array…他們完全沒有想過可以直接用 OpenNI 2 寫好的,或直接用 STL 現成的嗎? orz),裡面儲存的是目前偵測到的所有使用者。
不過由於這篇文章 Heresy 還不會仔細提 UserTrackerFrameRef 的各項功能細節,所以這邊就只有先使用他提供的 isNew() 和 isLost() 這兩個函式,來判斷這個使用者是剛被偵測到?還是不見了。包括骨架追蹤在內的細節,就等之後的文章再來說明了。
另外,如果要進行錯誤偵測的話,基本上也和 OpenNI 2 的方法(參考《OpenNI 2 的錯誤處理》)類似,只是回傳的狀態型別從 openni::Status 變成 nite::Status 而已。
這篇算是 NiTE2 的基本概論,大致上就先到這邊了。接下來應該是還會再花時間,針對 UserTracker 和 HandTracker 做進一步的說明(希望還有時間繼續寫下去…)。
您好,请问我想用python使用NITE,应该如何配置python呢?
讚讚
抱歉,Heresy 沒有使用 Python。
讚讚
Heresy您好:
我在您的NITE2範例程式編譯執行
nite::UserTracker mUserTracker;
mUserTracker.create() 一直傳回STATUS_ERROR
紅外線沒有亮起
官方程式(Bin裡的)可以正常執行
但是,使用OpenNI時候可以正常讀取深度以及彩色影像
最後我使用OpenNI先去抓取Kinect,再將裝置傳入NITE也是一樣
OpenNI 2.2 , NITE 2.2
Visual Studio 2013 C++
Windows 10 x64
謝謝
讚讚
請確認 Console 畫面是否有出現對應的錯誤訊息?
最有可能的問題,應該就是沒有正確地把 C:\Program Files\PrimeSense\NiTE2\Redist 下的檔案複製到執行的路徑。
讚讚
感謝你
複製過去就可以了
讚讚
您好,我按照您的步骤走的为何所有用到nite.h的代码都显示[下面的框架可能不正确和/或缺失,没有为 NiTE2.dll 加载符号]?
讚讚
抱歉,不過 Heresy 不知道這個訊息的英文、或是繁體中文的對應用語,不確定是什麼意思。
不過,建議請先確定這到底是錯誤、還是警告,是出現在哪裡?可以的話,麻煩提供截圖。
讚讚
问题详细的提问在这个连接的博客里,我遇到了通博主一样的问题。请您看看如何解决,谢谢!!http://q.cnblogs.com/q/73910/
讚讚
恩,老實說,你給的訊息只是一個警告,不是錯誤,而且算是最不重要的部分。
如果你的錯誤完全一樣,那重點是他的對話框內的錯誤訊息,還有你的程式是死在哪一行。
而基本上,下面的回答應該也就是答案了。
所以,這邊可能要請你釐清一下,你是執行的時候會有錯誤訊息?還是只是偵錯的時候會看到你貼的警告訊息?
讚讚
nite2 的网站 已经进不去了 请问老师在哪下载啊
讚讚
請參考: http://wp.me/p15GE3-46u
讚讚
您好,
有个问题想请教下,就是我的depth stream里面设置cropping,但是这个cropping却会影响我NiTE2的create(),一旦,我取消cropping,NiTE2的create()就成功,请问这个是什么问题呢?谢谢~
讚讚
這部分應該是 NiTE 本身的限制
讚讚
您好,我把NiTE 的初始化放在cropping 之前就没有问题了~
谢谢~
讚讚
您好,我有个问题想请教您一下,
在NiTE这里获取的骨架数据,能否在openni获得的深度数据中使用?
或者说,在openni获得的深度数据中,有没有办法判别画面中的某个点是属于人体还是背景?
我想实现的是,从深度图中,把人物抠出来。
谢谢您。
讚讚
UserTracker 本身就有提供這個功能了。
請使用 UserTrackerFrameRef 的 getUserMap() 這個函式。
範例:http://1drv.ms/1ivwkHy
請參考: https://kheresy.wordpress.com/2013/03/22/course-data-of-openni2-and-nite-2/
讚讚
谢谢您,我先学习一下,不懂的地方再请教您:)
讚讚
您好,我还有个问题要请教您,
我看了那个范例,运行看到结果了,但是getUserMap()的结果怎么保存下来呢,是什么样的数据呢?
我想实现的是,把人物抠出来之后,只要人物的深度数据,以便后期我对人物的多个角度的深度数据的registration。
谢谢。打扰您了。
讚讚
這部分沒有什麼一定的方法,只是看你自己怎樣儲存/讀取這種資料比較方便而已。
要單純化,就是把它當成圖檔來處理吧。
讚讚
好的,谢谢您。
讚讚
您好,想请问一下
如何用nite分析獲取已經錄好的oni格式的視頻中的人體骨架
感覺好像nite會默認kinect為輸入,有地方可以設置麼?
謝謝
讚讚
我在您的《OpenNI 2 的資料錄製與重播》中找到答案了
謝謝
讚讚
問題解決就好 :)
讚讚
[…] 的人體骨架追蹤》,提過怎麼在 OpenNI 2 的環境下,使用 NiTE2 這個函式庫,來做人體骨架的追蹤了。當時 Heresy […]
讚讚
Hi,Heresy.
I install NiTE2 and try to use it. But I get an error message from NiTE::initialize() .
I don’t know the reason, can you help me with it?
讚讚
Please provide the error message.
And please check if NiTE related files (ex: NiTE2.dll) are in the right directory.
讚讚
I found that NiTE 2.2.0.11 should use OpenNI2.2, but I use OpenNI2.1, this may be the problem. :)
讚讚
Yes, that may be the problem
讚讚
[…] Node」、也就是可以用來修改取得道的深度資料、讓之後的 middleware(PrimeSense NiTE)可以使用。(參考《修改 User Generator […]
讚讚