Kinect for Windows SDK開發入門(十八):Kinect Interaction互動控制項

來源:互聯網
上載者:User

    今年三月份發布了1.7版本的SDK,這一版本的SDK較前一版本最大的變化是添加了Kinect Interactions 和 Kinect Fusion。Kinect Interactions 提供了一些新的帶有姿勢識別的控制項如 push-to-press 按鈕, grip-to-pan 清單控制項, 而且支援多使用者,同時二個人進行的互動,這些新添加的控制項能夠非常方便的整合到應用程式中,極大的簡化了開發和調試過程。

    1.7 SDK中新增的第二個功能是去年在Build 2012大會上提到的Kinect Fusion,他能夠使我們能快速的建立對象的3D模型,能夠用到3D列印,建模,工業設計以及虛擬現實中去。

    在Kinect Developer ToolKit中,提供了ControlBasic-WPF, Kinect Interactions和Kinect Fusion的Demo,其中後兩個Demo對電腦的螢幕解析度和顯卡的要求比較高,運行Kinect Interactions需要1920*1080的解析度,而Kinect Fusion則需要良好的GPU才能進行即時渲染。

    基於以上原因,本文簡要展示Kinect Interactions中提供的新的控制項和互動方式。

建立必要環境

    建立工程之前,您需要到官網上下載最新的1.7 SDK和Developer Toolkit。首先開啟Visual Studio建立一個簡單的WPF傳統型應用程式,然後添加Microsoft.Kinect.dll , Kinect.Toolkit.dll, Kinect.Toolkit.Controls.dll和Kinect.Toolkit.Interaction.dll 引用,這些dll一般在安裝目錄下,我的機器上是C:\Program Files\Microsoft SDKs\Kinect\下面。

使用KinectSensorChooser控制項初始化Kinect感應器

    在Microsoft.Kinect.Toolkit.Controls命名空間下,最先用到的控制項可能就是KinectSensorChooserUI,它用來指示當前Kinect的工作狀態,提示使用者Kinect感應器是否工作正常,比如是否斷線,是否插到了錯誤的USB介面上了等等。

   要添加這個控制項,首先在主表單中,添加以下命名空間:

xmlns:k="http://schemas.microsoft.com/kinect/2013"

   然後,在主表單中添加KinectSensorChooserUI控制項,代碼如下:

<Grid>    <k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" Name="sensorChooserUi" /></Grid>

   在cs代碼中,我們需要初始化KinectSensorChooser控制項對象:

private KinectSensorChooser sensorChooser;

   然後在主表單的建構函式中註冊OnLoad事件:

public MainWindow(){    InitializeComponent();    Loaded += OnLoaded;}

   建立OnLoaded的委託方法:

private void OnLoaded(object sender, RoutedEventArgs e){    this.sensorChooser = new KinectSensorChooser();    this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;    this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;    this.sensorChooser.Start();}

    如果感應器的狀態發生改變,比如關閉或者初始化完成,將會觸發SensorChooserOnKinectChanged事件。現在為了示範方便,就用MessageBox彈出提示資訊:

private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args){    MessageBox.Show(args.NewSensor == null ? "No Kinect" : args.NewSensor.Status.ToString()); }

    現在運行系統。如果沒有將Kinect串連電腦上,您將會看到:

    在這種情況下,sensorChooser.Kinect ==null,如果將滑鼠移動到這個小方框上,他會咱開提供更多的資訊以及進一步操作的提示:

 

    這些SDK都幫你封裝好了,自己寫的話,可能需要花些時間。上面的help串連會鏈到K4W的官網上去。

    現在如果將Kinect感應器的USB連到電腦上,如果Kinect的電源線不串連,則會出現下列提示:

    現在把電源插上,現在KinectSensorChooserUI就會切換到初始化的模式下,將滑鼠以上去,回展開提示正在初始化:

    稍等一會兒,初始化完成之後,就可以看到Kinect的表徵圖 ,然後狀態變為初始化成功,這時回調方法就會執行,彈出MessageBox對話方塊。初始化完成之後,這個表徵圖就會從介面上消失,直到Kinect的狀態再次發生改變:

    這個表徵圖在Kinect Developer Kit中的Demo以及Kinect Studio中很多地方都用到,如果將該控制項稍加改造添加到您的應用程式中去,是不是很人性化,很簡單呢。

KinectSensorChooserUI控制項根據不同的狀態會嘗試給予使用者相應的提示,切換一下USB口,檢查Kinect的電源線是否連好等等。

建立Kinect互動的基本環境

    現在我們已經連上Kinect了,可以開始進行一些互動的基本設定。現在將SensorChooserOnKinectChanged 事件代碼補全:

private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args){    bool error = false;    if (args.OldSensor != null)    {        try        {            args.OldSensor.DepthStream.Range = DepthRange.Default;            args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;            args.OldSensor.DepthStream.Disable();            args.OldSensor.SkeletonStream.Disable();        }        catch (InvalidOperationException)        {            // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.            // E.g.: sensor might be abruptly unplugged.            error = true;        }    }    if (args.NewSensor != null)    {        try        {            args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);            args.NewSensor.SkeletonStream.Enable();            try            {                args.NewSensor.DepthStream.Range = DepthRange.Near;                args.NewSensor.SkeletonStream.EnableTrackingInNearRange = true;                args.NewSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;            }            catch (InvalidOperationException)            {                // Non Kinect for Windows devices do not support Near mode, so reset back to default mode.                args.NewSensor.DepthStream.Range = DepthRange.Default;                args.NewSensor.SkeletonStream.EnableTrackingInNearRange = false;            }        }        catch (InvalidOperationException)        {            error = true;            // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.            // E.g.: sensor might be abruptly unplugged.        }    }}

    上面的代碼可以處理舊的Kinect感應器拔掉,連上新的感應器並開啟深度和骨骼資料流的情景,在開發中我們可能會同時串連多個感應器。在try代碼中,我們試圖開啟近景模式,如果使用者採用的xbox感應器,則不支援,那麼轉到一般的模式下。一般情況下,開啟近景模式方便調試和使用者近距離使用。

二 Kinect 互動控制項

Kinect Region 控制項

    要想使用 Kinect Interaction,需要在介面上添加一個KinectRegion容器類。KinectRegion是WPF中使用Kinect Interaction進行互動的關鍵元素。它是其它Kinect interaction 控制項的容器。KinectRegion也負責展示和移動手形圖示,即使用者的手部骨骼點在介面上的展現。應用程式主介面上可以有多個KinectRegion,但是每個KinectRegion不能夠嵌套,每一個KinectRegion中可以有自己的Kinect sensor 對象。

    現在,添加一個KinectRegion對象到主表單上:

<k:KinectRegion Name="kinectRegion"></k:KinectRegion>

    然後,設定kinectRegion的KinectSensor屬性到我們擷取的kinectSensor上:

if (!error)    kinectRegion.KinectSensor = args.NewSensor;

    如果運行程式,則會提示錯誤:

    這個錯誤很常見,提示找不到KinectInteraction170_32.dll。在哪裡去找呢? 最簡單的辦法是到K4W SDK 的安裝路徑下面去尋找,找到後,根據當前作業系統的版本,將32位或者64位的dll拷貝到項目的輸出路徑。

 

    再次運行程式,可能需要10-20s的事件來初始化識別,如果一切正常,則會在應用程式上顯示手形游標:

    為了和示範,這裡有個小技巧,因為要示範,示範的時候必須距離Kinect一定的距離,這樣手夠不著鍵盤的PrintScreen鍵,所以推薦大家使用Kinect Studio 來錄製Kinect擷取的資料,然後播放該資料來對Kinect應用程式進行調試,這樣可以極大提高調試的效率,不必每次都站在Kinect前面進行操作。我先把動作錄下來,然後進行截屏或者錄屏製作動畫,這樣方便很多。

KinectUserViewer控制項

    有時在應用程式中,我們希望能夠顯示使用者自己的影像,以便給予一些反饋,在Kinect.Toolkit.Controls中有KinectUserViewer控制項, 可以使用該控制項來展示人物的深度影像,要使用它,需要在主介面上定義一個KinectUserViewer對象:

<k:KinectUserViewer VerticalAlignment="Top" HorizontalAlignment="Center"  k:KinectRegion.KinectRegion="{Binding ElementName=kinectRegion}" Height="100" />

    KinectUserViewer展示的是人物在Kinect中的深度影像資料,如果看不到影像,那麼表示當前Kinect沒有追蹤到你,這時應當試著移動來讓Kinect追蹤到你。運行程式,還是使用剛才Kinect Studio錄製到的資料,這時您可以看到自己在Kinect視場中的人物深度影像。

    前面的控制項用來展現了當前的Kinect狀態,手形位置,以及人物在kinect中的深度影像,這些都可以給使用者一些全域的反饋,表示當前系統運行正常,現在我們要使用一些基本的控制項來真正的和應用程式來進行互動。

KinectTileButton

    首先要介紹的是KinectTileButton控制項,他也是最簡單的一個控制項,有點兒像Win8 裡面的Metro貼片,他其實是一個普通的button控制項,只不過通過Kinect用手來類比滑鼠的行為,現在我們添加一個KinectTileButton到介面上來玩玩。

<k:KinectTileButton Label="Press me!" Click="ButtonOnClick"></k:KinectTileButton>

    然後在click事件裡面寫一些提示:

private void ButtonOnClick(object sender, RoutedEventArgs e){    MessageBox.Show("You clicked me!");}

    當我們的手沒有接觸到該控制項的時候,他預設為藍色。當手移動到按鈕上時,按鈕會變大,並且手形圖示周圍會出現陰影,以顯示當前處於懸浮狀態。然後我們將手掌像Kinect方向推,會發現手形圖示會根據距離Kinect的距離遠近來產生動畫,表示我們正在產生“壓”按鈕的動作。當達到一定的深度閾值時,表示使用者已經按下按鈕,手形圖示會變色,並且會觸發Click事件。

 

KinectCircleButton

    KinectCircleButton和KinectTileButton類似,只不過按鈕的形狀是圓形的,這個可以從名字中可以看出來。要把KinectCircleButton添加到已有的介面布局中,我們需要稍微調整一下。KinectRegion是一個內容控制項,表示裡面只能有一個子控制項,但是,這個子控制項可以是一個包含其他容器如Grid或者StackPanel的控制項。現在我們需要將之前的KinectTileButton包含到一個Grid控制項中,然後將KinectTileButton移到左邊,然後在右邊添加一個KinectCircleButton控制項。

<k:KinectCircleButton Label="Circle" HorizontalAlignment="Right" Height="200" VerticalAlignment="Top" Click="ButtonOnClick" >Hi</k:KinectCircleButton>

    重複以上動作,可以看到相似的動畫效果:

    需要指出的是,這兩個控制項也可以用滑鼠進行操作。

KinectScrollViewer

    在K4W 1.7 SDK之前,要實現使用Kinect瀏覽列表,並選擇是比較困難的,但是在最新的1.7 SDK中推出的KinectScrollViewer控制項極大地簡化了這一操作。現在,我們在表單底部放置一個KinectScrollViewer。將下面的代碼添加到KinectRegion內部的Grid中:

<k:KinectScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Bottom">    <StackPanel Orientation="Horizontal" Name="scrollContent" /></k:KinectScrollViewer>

    這個控制項就像WPF中的標準ScrollViewer一樣。裡面有一個StackPanell用來放置滾動的內容,這兩個控制群組合可以使得內容水平滾動,現在在StackPanel中放置一些KinectCircleButtons.

for (int i = 1; i < 20; i++){    var button = new KinectCircleButton    {        Content = i,        Height = 200    };    int i1 = i;    button.Click +=        (o, args) => MessageBox.Show("You clicked button #" + i1);    scrollContent.Children.Add(button);}

    現在運行程式,如動畫所示,剛開始的時候,可以看到下面的KinectCircleButton;當手移動手到捲動區域,顏色發生變化;然後合上手指,握拳,手勢表徵圖會發生變化,表示你當前正在對KinectScrollViewer做抓取操作,移動拳頭,KinectScrollViewer控制項會把手勢表徵圖貼到控制項上,就像我們的手指在觸控螢幕上操作那樣,然后里面的button會跟著手勢的移動而移動,定位好了之後,放開拳頭,就停止移動,這個時候, 對著想要的按鈕,將手往前壓,就會像前面的控制項那樣觸發Click事件。

 

    說點兒題外話,上面的這個動畫錄製的有點兒大,有5M多,導致我在Windows Live Write中往部落格園中發布的時候,總是提示如下500錯誤:

    Google了一下,有的說是圖片太大的緣故,於是下載了一個叫Ulead Gif Animator的編輯GIF動畫的軟體,刪掉了一些重複幀,並縮小了尺寸。再次發布就沒有這個錯誤了。

結語

    本文簡要介紹了Kinect for Windows 1.7 SDK中引入的Kinect Interactions功能及相關控制項,這些具有Kinect屬性的控制項極大地簡化了我們將Kinect功能添加到應用程式中去的難度,使得我們能夠通過Kinect更快更好的建立炫酷的Kinect應用程式。本文的代碼點擊此處下載,由於大小關係,代碼中沒有放置KinectInteraction170_32.dll或者KinectInteraction170_64.dll 這兩個dll,您自己安裝SDK後拷貝到對應目錄下運行即可,希望本文對您瞭解1.7 版 SDK 中的Kinect Interactions 相關控制項有所協助。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.