PrimeSense 推出新的 Grab Detector

| | 4 Comments| 13:20
Categories:

PrimeSense 的 NiTE 主要是提供了人的骨架追蹤,以及手部追蹤的功能,基本上應該算是在 OpenNI 這個架構下,最重要、也最常被使用的 middleware library 了。不過由於他的手部追蹤的功能,僅能提供位置的追蹤、和簡單的動態手勢辨識,並沒有辦法去針對手的狀態、或是手指作分析,算是比較可惜的地方。

而現在,PrimeSense 又推出了一套新的 middleware library:Grab Detector,可以用來檢查使用者的手是否有做出抓(grab)的動作了!他的網址是:http://www.openni.org/files/grab-detector/,目前有提供 Windows 版的 32 / 64 位元程式,讓開發者可以使用了~

目前的版本下載後,會是一個「Demo.zip」的壓縮檔,在解開後,裡面會有一個「GrabDetector.pdf」的說明文件,解釋他的「grab」手勢、以及基本使用的概念;而函式庫本身,則是放在「Redistributable」這個目錄,「Demo」目錄底下,就是官方提供的範例程式。比較可惜的是,它可以用來參考的文件並不多,所以應該是得看著 API 和範例來摸索了。

根據文件的說法,這個函式庫和 NiTE 只需要深度影像不同,Grab Detector 同時需要深度影像與彩色影像,並且設定位置校正、以及同步後,才能正常運作(參考)。比較適當的操作距離,是建議在 2-2.5M 之間,同時,由於也需要彩色影像,所以室內不要太暗,會有比較好的效果。

所以,如果是沒有彩色影像的 ASUS Xtion Pro,基本上就不能用了。而如果是使用 Kinect 感應器的話,由於 OpenNI 2 官方的模組並不支援影像位置校正的功能,所以必須要去使用修改過的 Kinect.dll 才行(參考)。

不過實際上,如果進去看他的 API 的話,可以發現,實際上 Grab Detector 在只有深度影像的情況下,還是可以運作的!不過效果會變比較差就是了。

如果是想測試他的效果的話,可以執行「\Demo\Win32\Release」目錄下的「GrabViewer.exe」這個程式(或是也可以執行 64 位元的版本);他執行起來後的畫面,大致上會如下圖:

基本上,由於他是先使用 NiTE 的 Hand Tracker 來做手的追蹤,然後再透過 Grab Detector 來做分析,所以一開始要使用「Click」(手往前推出再收回)或「Wave」(揮手)、來完成手的定位。

而接下來,他就會開始針對手的姿勢來做分析、偵測 grab 這個手勢了~而 Grab Detector 定義的「grab」的手勢,基本上如下面的圖片:

他基本上是定義把五隻手指靠攏為「grab」、用來做偵測。而他也有特別提到,建議不要用握拳的形式來做,雖然可能也會成功,但是效果會比較差。而如果要釋放的話,基本上就是把手張開就好了。

如果手勢變化的事件有成功地偵測到的話,應該會看到畫面上手上的「RELEASE」會變成「GRAB」的字樣,而另外一個命令提示字元視窗,也會有對應的文字出現。

在 Heresy 這邊自己測試的話,感覺效果算是還不錯了~


而如果想知道程式該怎麼寫的話,則是可以參考「Demo\Samples\GrabViewer」底下的專案。

實際上真的要寫的話,它必要的檔案都放在「Redistributable」這個目錄下,「Common」裡面的兩個 header 檔,就是要使用時所需要的 header 檔;而「data」目錄裡面則是在執行階段需要的資料檔案。Windows 平台上所需要的 lib 和 dll 檔,則分別在 Win32x64 這兩個資料夾內,可以根據自己建置的程式平台來使用。

要使用 Grab Detector 的話,大致上會是這樣的流程:

  1. include GrabDetector.h 這個檔案,然後所需要的物件會在 PSLabs 這個 namespace 下。

  2. 按照一般的流程,建立 OpenNI NiTE 的程式,包括了初始化 OpenNI 環境、建立需要的 VideoStream 並完成相關設定,以及初始化 NiTE 環境、建立出 HandTracker、並完成設定。

  3. 透過 PSLabs::CreateGrabDetector() 建立出 PSLabs::IGrabDetector 的物件,來做後續的操作。
    在建立時,要指定要使用的 Device、以及所需要的資料檔(Redistributable\Common\Data\grab_gesture.dat)所在的路徑。

  4. 透過 PSLabs::IGrabDetectorAddListener() 函式,來設定當事件觸發時,要做什麼事。

    • 這邊基本上是要繼承 PSLabs::IGrabEventListener 來寫一個新的類別,並在這個類別裡面實作 ProcessGrabEvent() 這個函式,針對不同的事件,作個別的處理。
      他接到的資料會是 PSLabs::IGrabEventListener::EventParams,透過他的 Type 變數,可以知道現在的事件是什麼;這包括了 GRAB_EVENTRELEASE_EVENT 以及 NO_EVENT 三種可能。

  5. 接下來,進入主迴圈後,則是每次透過 PSLabs::IGrabDetector 提供的 SetHandPosition() 來設定目前手的位置(可由 HandTracker 取得),並透過 UpdateFrame() 來提供新的深度、彩色畫面。

    • 這邊是說需要 VGA 解析度(640 x 480)的影像。

    • 雖然文件是說要有彩色、深度影像,不過實際上僅有深度影像也可以使用,但是效果會較差。

  6. 程式結束後,透過 PSLabs::ReleaseGrabDetector() 來釋放掉 PSLabs::IGrabDetector 這個物件。

而如果不想使用 Listener/callback 的形式來使用 Grab Detector 的話,也可以在主迴圈內,透過 PSLabs::IGrabDetectorGetLastEvent() 來取得最後一個事件,藉此來做處理。

不過另外要注意的是,這個函式庫從界面來看,應該只能針對一只手作偵測而已,還不確定要怎麼針對兩隻(或以上)的手做偵測;或許之後有空再來研究看看吧?


這篇大致上就先這樣了,Heresy 自己有成功地寫出一個簡單的程式、可以成功地偵測到手勢的變化,所以應該是可以用沒問題的。完整的範例,就晚一點再放出來吧~

另外,其實如果純以 OpenNI 的深度圖,搭配 OpenCV,其實也可以針對手部做一些分析(參考),真的要的話,應該也可以做到一定的程度地辨別?或許之後試試看能不能拿這個方法,來便是手是否是張開的吧~


OpenNI / Kinect 相關文章目錄

4 thoughts on “PrimeSense 推出新的 Grab Detector”

  1. heresy大大,运行不了啊,分析不出问题。openni2_GrabDetector.obj : error LNK2019: 无法解析的外部符号 _ReleaseGrabDetector@4,该符号在函数 _main 中被引用
    1>openni2_GrabDetector.obj : error LNK2019: 无法解析的外部符号 _CreateGrabDetectorFromHandle@8,该符号在函数 “class PSLabs::IGrabDetector * __stdcall PSLabs::CreateGrabDetector(class openni::Device &,char const *)” (?CreateGrabDetector@PSLabs@@YGPAVIGrabDetector@1@AAVDevice@openni@@PBD@Z) 中被引用
    1>C:Documents and Settingslcmy documentsvisual studio 2010Projectsopenni2_GrabDetectorDebugopenni2_GrabDetector.exe : fatal error LNK1120: 2 个无法解析的外部命令
    1>

  2. to chao

    請確認專案在編譯時、編譯器有正確連結到正確的 GrabDetector.lib 這個檔案。

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *