C# 實現Kinect 按鈕功能

前一篇博客中,作者介紹瞭如何用微軟的Kinect識別手勢。用戶的雙手揮動時,Kinect可以識別雙手的位置,並實時把位置數據顯示在屏幕上。如何實現當用戶的雙手經過一個按鈕時,軟件識別這個按鈕,達到一定時間後自動點擊這個按鈕?

下面我們用C# + WPF來實現這個功能。

首先我們在界面上設置三個普通按鈕,並定義它們的點擊事件。


<Button x:Name="button1" Width="200" Height="100" Content="button1" FontSize="26" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Canvas.Left="157" Canvas.Top="108" />

<Button x:Name="button2" Width="200" Height="100" Content="button2" FontSize="26" Canvas.Left="483" Canvas.Top="108" />

<Button x:Name="quitButton" Background="Gray" Content="Exit" FontSize="26" Click="quitButton_Click" Canvas.Left="580" Canvas.Top="396" Height="84" Width="103" />

定義一個label,來提示按鈕的點擊狀態:

<Label Canvas.Left="157" Canvas.Top="253" Content="Label" Height="43" Name="label1" Width="200" FontSize="18" />

定義Kinect的鼠標,其中:TimeInterval="2000"是動畫播放的延時,2000代表延時2秒

<Controls:HoverButton x:Name="_rightHand" ImageSize="50" TimeInterval="2000" Panel.ZIndex="2" ImageSource="/images/rightHand.png" ActiveImageSource="/images/rightHand.png"/>

在代碼中,把所有按鈕放在一個List<Button>buttons; 裏面

private void InitializeButtons()
        {
            buttons = new List<Button> { button1,button2,quitButton };            
        }

接收Kinect的骨骼數據:


KinectLib.KinectCorrection = 0.5f;
KinectLib.KinectJitterRadius = 0.05f;
KinectLib.KinectMaxDeviationRadius = 0.04f;
KinectLib.KinectPrediction = 0.1f;
KinectLib.KinectSmoothing = 0.5f;
KinectLib.KinectMsg = "Runtime initialization failed. Please make sure Kinect device is plugged in.";
KinectLib.iniKinect();//start kinect
KinectLib._receiveHandPositions += new receivePoints(KinectLib__receiveHandPositions); //Receive joints<span style="color: rgb(0, 0, 255); "> 
</span>


接收到雙手的位置數據後,用isHandOver(this._rightHand,buttons)這個函數檢測手是否經過一個按鈕,如果是,則播放動畫,動畫播放時間達到預設的時間,則自動觸發按鈕點擊事件。

關鍵代碼:

void KinectLib__receiveHandPositions(Joint joints, double x, double y, double z)
        {
            if (joints.ID == JointID.HandRight)
            {
                Canvas.SetLeft(this._rightHand, x);
                Canvas.SetTop(this._rightHand, y);
                if (isHandOver(this._rightHand, buttons))
                {
                    this._rightHand.Hovering();
                }
                else
                {
                    this._rightHand.Release();
                }
            }
        }

private bool isHandOver(FrameworkElement hand, List<Button> buttonslist)
        {
            var handTopLeft = new Point(Canvas.GetLeft(hand), Canvas.GetTop(hand));
            var handX = handTopLeft.X + hand.ActualWidth / 2;
            var handY = handTopLeft.Y + hand.ActualHeight / 2;

            foreach (Button target in buttonslist)
            {
                Point targetTopLeft = new Point(Canvas.GetLeft(target), Canvas.GetTop(target));
                if (handX > targetTopLeft.X &&
                    handX < targetTopLeft.X + target.Width &&
                    handY > targetTopLeft.Y &&
                    handY < targetTopLeft.Y + target.Height)
                {
                    selected = target;
                    return true;
                }
            }
            return false;
        }


 

要運行本文範例,你需要安裝 MicrosoftKinect 驅動(for Xbox360)

本文範例(C#)下載









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章