Kinect for Windows SDK開發入門(八)骨骼追蹤進階 上

來源:互聯網
上載者:User

前7篇檔案我們介紹了Kinect SDK中各種感應器的各種基本知識,我們用實驗的方式示範了這些基本對象和方法的如何使用,這些都是Kinect開發最基本的知識。瞭解了這些基本知識後,就可以開發出一個基於Kinect的簡單程式了。但是這些離開發出一個好的基於Kinect的應用程式還有一段距離。後面的文章中,將會結合Kinect SDK介紹WPF以及其它第三方工具,類庫來建立一個以Kinect為驅動的有較好使用者體驗的程式。我們將利用之前講到的知識來進行下面一些比較複雜的話題。

Kinect感應器核心只是發射紅外線,並探測紅外光反射,從而可以計算出視場範圍內每一個像素的深度值。從深度資料中最先提取出來的是物體主體和形狀,以及每一個像素點的遊戲者索引資訊。然後用這些圖形資訊來匹配人體的各個部分,最後計算匹配出來的各個關節在人體中的位置。這就是我們之前介紹過的骨骼追蹤。

紅外影像和深度資料對於Kinect系統來說很重要,它是Kinect的核心,在Kinect系統中其重要性僅次於骨骼追蹤。事實上,這些資料相當於一個輸入終端。隨著Kinect或者其他深度攝像機的流行和普及。開發人員可以不用關注原始的深度影像資料,他們變得不重要或者只是作為擷取其他資料的一個基礎資料而已。我們現在就處在這個階段,Kinect SDK並沒有提供給開發人員訪問原始紅外影像資料流的介面,但是其它第三方的SDK可以這麼做。可能大多數開發人員不會使用原始的深度資料,用到的只是Kinect處理好了的骨骼資料。但是,一旦姿勢和手勢識別整合到Kinect SDK並成為其一部分時,可能開發人員甚至不用接觸到骨骼資料了。

希望能夠早日實現這種整合,因為它代表這Kinect作為一種技術的走向成熟。本篇文章和下篇文章仍將討論骨骼追蹤,但是採用不同的方法來處理骨骼資料。我們將Kinect作為一個如同滑鼠,鍵盤或者觸控螢幕那樣的一個最基本的輸入裝置。微軟當初推出Kinect for Xbox的口號是“你就是控制器”,從技術方面講,就是“你就是輸入裝置”。通過骨骼資料,應用程式可以做滑鼠或者觸控螢幕可以做的事情,所不同的是深度影像資料使得使用者和應用程式可以實現以前從沒有過的互動方法。下面來看看Kinect控制並與使用者介面進行互動的機制吧。

1. 使用者互動

運行在電腦上的應用程式需要輸入資訊。傳統的資訊來自於滑鼠或者鍵盤等這些輸入裝置。使用者直接與這些硬體裝置進行互動,然後硬體裝置響應使用者的操作,將這些操作轉換成資料轉送到電腦中。電腦接收這些輸入裝置的資訊然後將結果以可視化的形式展現出來。大多數電腦的映像使用者介面上會有一個游標(Cursor),他通常代表滑鼠所在的位置,因為滑鼠是最開始有個滾輪裝置。但是現在,如果將這個游標指代滑鼠游標的話,可能不太準確,因為現在一些觸摸板或手寫裝置也能像滑鼠那樣控制游標。當使用者移動滑鼠或者在觸摸板上移動手指時,游標也能響應這種變化。當使用者將游標移動到一個按鈕上時,通常按鈕的外觀會發生變化,提示使用者游標正位於按鈕上。當使用者點擊按鈕時,按鈕則為顯示另一種外觀。當使用者鬆開滑鼠上的按鍵,按鈕就會出現另外一種外觀。顯然,簡單的點擊事件會涉及到按鈕的不同狀態。

開發人員可能對這些互動介面和操作習以為常,因為諸如WPF之類的使用者互動平台使得程式與使用者進行互動變得非常簡單。當開發網頁程式時,瀏覽器響應使用者的互動,開發人員只需要根據使用者滑鼠的懸停狀態來設定樣式即可進行互動。但是Kinect不同,他作為一個輸入裝置,並沒有整合到WPF中去,因此,作為一個開發人員。對作業系統和WPF所不能直接響應的那部分工作需要我們來完成。

在底層,滑鼠,觸摸板或者手寫裝置都是提供一些X,Y座標,作業系統將這些X,Y座標從其在的空間座標系統轉換到電腦螢幕上,這一點和上篇文章討論的空間變換類似。作業系統的職責是響應這些標準輸入裝置輸入的資料,然後將其轉換到圖形化使用者介面或者應用程式中去。作業系統的圖形化使用者介面顯示光線標位置,並響應使用者的輸入。在有些時候,這個過程沒有那麼簡單,需要我們瞭解GUI平台。以WPF應用程式為例,它並沒有對Kinect提供像滑鼠和鍵盤那樣的原生的支援。這個工作就落到開發人員身上了,我們需要從Kinect中擷取資料,然後利用這些資料與按鈕,下拉框或者其他控制項進行互動。根據應用程式或者使用者介面的複雜度的不同,這種工作可能需要我們瞭解很多有關WPF的知識。

1.1 WPF應用程式中輸入系統介紹

當開發一個WPF應用程式時,開發人員並不需要特別關注使用者輸入機制。WPF會為我們處理這些機制使得我們可以關注於如何響應使用者的輸入。畢竟作為一個開發人員,我們更應該關心如何對使用者輸入的資訊進行分析處理,而不是重新造輪子來考慮如何去收集使用者的輸入。如果應用程式需要一個按鈕,只需要從工具箱中拖一個按鈕出來放在介面上,然後在按鈕的點擊事件中編寫處理邏輯即可。在大多數情況下,開發人員可能需要對按鈕設定不同的外觀以響應使用者滑鼠的不同狀態。WPF會在底層上為我們實現這些事件,諸如滑鼠何時懸停在按鈕上,或者被點擊。

WPF有一個健全的輸入系統來從輸入裝置中擷取使用者的輸入資訊,並響應這些輸入資訊所帶來的控制項變化。這些API位於System.Windows.Input命名空間中(Presentation.Core.dll),這些API直接從作業系統擷取輸入裝置輸入的資料,例如,名為Keyboard,Mouse,Stylus,Touch和Cursor的這些類。InputManager這個類負責管理所有輸入裝置擷取的資訊,並將這些資訊傳遞到表現架構中。

WPF的另一類組件是位於System.Windows命名空間(PresentationCore.dll)下面的四個類,他們是UIElement,ContentElement,FrameworkElement以及FrameworkContentElement 。FrameworkElement繼承自UIElement,FrameworkContentElement繼承自ContentElement。這幾個類是WPF中所有可視化元素的基類,如Button,TextBlock及ListBox。更多WPF輸入系統相關資訊可以參考MSDN文檔。

InputManager監聽所有的輸入裝置,並通過一系列方法和事件來通知UIElement和ContentElement對象,告知這些對象輸入裝置進行了一些有關可視化元素相關的操作。例如,在WPF中,當滑鼠游標進入到可視化控制項的有效地區時就會觸發MouseEnterEvent事件。UIElement和ContentElement對象也有OnMouseEnter事件。這使得任何繼承自UIElement或者ContentElement類的對象也能夠接受來自輸入裝置的所觸發的事件。WPF會在觸發任何其它輸入事件之前調用這些方法。在UIElement和ContentElement類中也有一些類似的事件包括MouseEnter,MouseLeave,MouseLeftButtonDown,MouseLeftButtonUp,TouchEnter,TouchLeave,TouchUp和TouchDown。

有時候開發人員需要直接存取滑鼠或者其他輸出裝置,InputManager對象有一個稱之為PrimaryMouseDevice的屬性。他返回一個MouseDevice對象。使用MouseDevice對象,能夠在任何時候通過調用GetScreenPositon來擷取滑鼠的位置。另外,MouseDevice有一個名為GetPositon的方法,可以傳入一個UI介面元素,將會返回在該UI元素所在的座標空間中的滑鼠位置。當需要判斷滑鼠移至上方等操作時,這些資訊尤其重要。當Kinect SDK每一次產生一幅新的SkeletonFrame幀資料時,我們需要進行座標空間轉換,將關節點位置資訊轉換到UI空間中去,使得可視化元素能夠直接使用這些資料。當開發人員需要將滑鼠作為輸入裝置時, MouseDevice對象中的GetScreenPositon和GetPosition方法能提供當前滑鼠所在點的位置資訊。

在有些情況下,Kinect雖然和滑鼠相似,但是某些方面差別很大。骨骼節點進入或者離開UI上的可視化元素這一點和滑鼠移入移出行為類似。換句話說,關節點的懸停行為和滑鼠游標一樣。但是,類似滑鼠點擊和滑鼠按鍵的按下和彈起這些互動,關節點與UI的互動是沒有。在後面的文章中,可以看到使用手可以類比點擊操作。在Kinect中相對於實現滑鼠移入和移出操作來說,對滑鼠點擊這種支援相對來說較弱。

Kinect和觸摸板也沒有太多相同的地方。觸摸輸入可以通過名為Touch或者TouchDevice的類來訪問。單點的觸摸輸入和滑鼠輸入類似,然而,多點觸控是和Kinect類似的。滑鼠和UI之間只有一個互動點(游標)但是觸摸裝置可以有多個觸控點。就像Kinect可以有多個遊戲者一樣。從每一個遊戲者身上可以捕捉到20個關節點輸入資訊。Kinect能夠提供的資訊更多,因為我們知道每一個輸入焦點是屬於遊戲者身體的那個部位。而觸控輸入裝置,應用程式不知道有多少個使用者正在觸控螢幕幕。如果一個程式接收到了10個輸入焦點,無法判斷這10個點是一個人的10個手指還是10個人的一個手指觸發的。 雖然觸控裝置支援多點觸控,但這仍然是一種類似滑鼠或者手寫板的二維的輸入。然而,觸控輸入裝置除了有X,Y點座標外,還有觸控接觸面積這個欄位。畢竟,使用者用手指按在螢幕上沒有滑鼠游標那樣精確,觸控接觸面積通常大於1個像素。

當然,他們之間也有相似點。Kinect輸入顯然嚴格地符合WPF 所支援的任何輸入裝置的要求。除了有其它輸入裝置類似的輸入方式外,他有獨特的和使用者進行互動的方式和圖形化使用者介面。核心上,滑鼠,觸控板和手寫板只傳遞一個像素點位置嘻嘻你。輸入系統確定該點在可見元素上下文中的像素點位置,然後這些相關元素響應這個位置資訊,然後進行響應操作。

期望是在未來Kinect能夠完整的整合進WPF。在WPF4.0中,觸控裝置作為一個單獨的模組。最開始觸控裝置被作為微軟的Surface引入。Surface SDK包括一系列的WPF控制項,諸如SurfaceButton,SurfaceCheckBox,和SurfaceListBox。如果你想按鈕能夠響應觸摸事件,最好使用SurfaceButton控制項。

能夠想象到,如果Kinect被完整的整合進WPF,可能會有一個稱之為SkeletonDevice的類。他和Kinect SDK中的SkeletonFrame對象類似。每一個Skeleton對象會有一個稱之為GetJointPoint的方法,他和MouseDevice的GetPositon和TouchDevice的GetTouchPoint類似。另外,核心的可視化元素(UElement, ContentElement, FrameworkElement, FrameworkContentElement) 有能夠相應的事件或者方法能夠通知並處理骨骼關節點互動。例如,可能有一個JointEnter,JointLeave,和JointHover事件。更進一步,就像觸控類有一個ManipulationStarted和ManipulationEnded事件一樣,在Kinect輸入的時候可能伴隨GetstureStarted和GestureEnded事件。

目前,Kinect SDK和WPF是完全分開的,因此他和輸入系統沒有在底層進行整合。所以作為開發人員的我們需要追蹤骨骼關節點位置,並判斷節點位置是否和UI介面上的元素有互動。當關節點在對應的UI座標系可視化介面的有效範圍內時,我們必須手動的改變這些可視化元素的外觀以響應這種互動。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.