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 做進一步的說明(希望還有時間繼續寫下去…)。
能问个问题吗:每次我运行的时候,程序都会
mUserTracker.create();在这个死掉,但是编译是通过的,运行到这程序就不向下运行了。
还有一些提示:
“TLD.exe”: 已加载“H:\OpenCV\TLD\x64\Debug\TLD.exe”,已加载符号。
“TLD.exe”: 已加载“C:\Windows\System32\ntdll.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\kernel32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\KernelBase.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“H:\OpenCV\TLD\TLD\OpenNI2.dll”,已加载符号。
“TLD.exe”: 已加载“C:\Windows\System32\msvcr100.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“H:\OpenCV\TLD\TLD\NiTE2.dll”,已加载符号。
“TLD.exe”: 已加载“C:\Windows\System32\msvcp100.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msvcp100d.dll”,已加载符号。
“TLD.exe”: 已加载“C:\Windows\System32\msvcr100d.dll”,已加载符号。
“TLD.exe”: 已加载“H:\OpenCV\TLD\TLD\OpenNI2\Drivers\KinectMod64.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\mscoree.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\Kinect10.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\winmm.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msvcrt.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\user32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\gdi32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\lpk.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\usp10.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\advapi32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\sechost.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\rpcrt4.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\ole32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\oleaut32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\setupapi.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\cfgmgr32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\devobj.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\winusb.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\crypt32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msasn1.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\imm32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msctf.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\nvinitx.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\wintrust.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoreei.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\shlwapi.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msvcr100_clr0400.dll”,Cannot find or open the PDB file
TLD.exe 中的 0x000007fefe1bbccd 处最可能的异常: 0x04242420: 0x4242420
“TLD.exe”: 已加载“C:\Windows\assembly\NativeImages_v4.0.30319_64\mscorlib\a009da37f5d41055d73cfb9b04419743\mscorlib.ni.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\nlssorting.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clrjit.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\uxtheme.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\apphelp.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\GooglePinyin2.ime”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\shell32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\version.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\winsxs\amd64_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7601.17514_none_a4d6a923711520a9\comctl32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\msimg32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\winsxs\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17825_none_2b253c8271ec7765\GdiPlus.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\dbghelp.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\userenv.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\profapi.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\wininet.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\normaliz.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\iertutil.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\urlmon.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\cryptbase.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\dwmapi.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“D:\360安全卫士\Youdao\Dict\5.3.40.8020\WordStrokeHelper64.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“H:\OpenCV\TLD\TLD\OpenNI2\Drivers\OniFile.dll”,已加载符号。
“TLD.exe”: 已加载“H:\OpenCV\TLD\TLD\OpenNI2\Drivers\PS1080.dll”,已加载符号。
“TLD.exe”: 已加载“C:\Windows\System32\cryptsp.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\rsaenh.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\gpapi.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\ncrypt.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\bcrypt.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\bcryptprimitives.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\cryptnet.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\Wldap32.dll”,Cannot find or open the PDB file
“TLD.exe”: 已加载“C:\Windows\System32\SensApi.dll”,Cannot find or open the PDB file
线程 ‘Win64 线程’ (0x2074) 已退出,返回值为 0 (0x0)。
to wobuaishangdiao
請提供錯誤訊息,你給的訊息基本上並沒有辦法作為參考。
或者,請先試著執行 NiTE 本身的範例試試看,是否可以正常執行。
另外,也麻煩試著自行在程式內加上錯誤偵測,作為判斷。