2013-03-15 23 views
0

我在wpf中有一個kinect項目,它使用骨架流跟蹤用戶的左右手,並允許我將鼠標懸停在按鈕上。我如何將kinect跟蹤轉換成另一種形式

我試着製作一個新表格,只是複製和粘貼一切,所以我可以創建一個新頁面,但它沒有工作,我想我可能不得不引用主頁面中使用的方法,但我不確定。

我希望能夠使用骨架流沿着盤旋方法在新窗口中

任何幫助,將不勝感激 - 我道歉,如果這是沒有意義的我是一個初學者

代碼

public partial class MainWindow : Window 
    { 
     private KinectSensor _Kinect; 
     private WriteableBitmap _ColorImageBitmap; 
     private Int32Rect _ColorImageBitmapRect; 
     private int _ColorImageStride; 
     private Skeleton[] FrameSkeletons; 

     List<Button> buttons; 
     static Button selected; 

     float handX; 
     float handY; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      InitializeButtons(); 
      kinectButton.Click += new RoutedEventHandler(kinectButton_Click); 

      this.Loaded += (s, e) => { DiscoverKinectSensor(); }; 
      this.Unloaded += (s, e) => { this.Kinect = null; }; 
     } 

     //initialize buttons to be checked 
     private void InitializeButtons() 
     { 
      buttons = new List<Button> { button1, button2, quitButton}; 
     } 

     //raise event for Kinect sensor status changed 
     private void DiscoverKinectSensor() 
     { 
      KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged; 
      this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected); 
     } 

     private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e) 
     { 
      switch (e.Status) 
      { 
       case KinectStatus.Connected: 
        if (this.Kinect == null) 
        { 
         this.Kinect = e.Sensor; 
        } 
        break; 
       case KinectStatus.Disconnected: 
        if (this.Kinect == e.Sensor) 
        { 
         this.Kinect = null; 
         this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected); 
         if (this.Kinect == null) 
         { 
          MessageBox.Show("Sensor Disconnected. Please reconnect to continue."); 
         } 
        } 
        break; 
      } 
     } 

     public KinectSensor Kinect 
     { 
      get { return this._Kinect; } 
      set 
      { 
       if (this._Kinect != value) 
       { 
        if (this._Kinect != null) 
        { 
         UninitializeKinectSensor(this._Kinect); 
         this._Kinect = null; 
        } 
        if (value != null && value.Status == KinectStatus.Connected) 
        { 
         this._Kinect = value; 
         InitializeKinectSensor(this._Kinect); 
        } 
       } 
      } 
     } 

     private void UninitializeKinectSensor(KinectSensor kinectSensor) 
     { 
      if (kinectSensor != null) 
      { 
       kinectSensor.Stop(); 
       kinectSensor.ColorFrameReady -= Kinect_ColorFrameReady; 
       kinectSensor.SkeletonFrameReady -= Kinect_SkeletonFrameReady; 
      } 
     } 

     private void InitializeKinectSensor(KinectSensor kinectSensor) 
     { 
      if (kinectSensor != null) 
      { 
       ColorImageStream colorStream = kinectSensor.ColorStream; 
       colorStream.Enable(); 
       this._ColorImageBitmap = new WriteableBitmap(colorStream.FrameWidth, colorStream.FrameHeight, 
        96, 96, PixelFormats.Bgr32, null); 
       this._ColorImageBitmapRect = new Int32Rect(0, 0, colorStream.FrameWidth, colorStream.FrameHeight); 
       this._ColorImageStride = colorStream.FrameWidth * colorStream.FrameBytesPerPixel; 
       videoStream.Source = this._ColorImageBitmap; 

       kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters() 
       { 
        Correction = 0.5f, 
        JitterRadius = 0.05f, 
        MaxDeviationRadius = 0.04f, 
        Smoothing = 0.5f 
       }); 

       kinectSensor.SkeletonFrameReady += Kinect_SkeletonFrameReady; 
       kinectSensor.ColorFrameReady += Kinect_ColorFrameReady; 
       kinectSensor.Start(); 
       this.FrameSkeletons = new Skeleton[this.Kinect.SkeletonStream.FrameSkeletonArrayLength]; 

      } 
     } 

     private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) 
     { 
      using (ColorImageFrame frame = e.OpenColorImageFrame()) 
      { 
       if (frame != null) 
       { 
        byte[] pixelData = new byte[frame.PixelDataLength]; 
        frame.CopyPixelDataTo(pixelData); 
        this._ColorImageBitmap.WritePixels(this._ColorImageBitmapRect, pixelData, 
         this._ColorImageStride, 0); 
       } 
      } 
     } 

     private void Kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) 
     { 
      using (SkeletonFrame frame = e.OpenSkeletonFrame()) 
      { 
       if (frame != null) 
       { 
        frame.CopySkeletonDataTo(this.FrameSkeletons); 
        Skeleton skeleton = GetPrimarySkeleton(this.FrameSkeletons); 

        if (skeleton == null) 
        { 
         kinectButton.Visibility = Visibility.Collapsed; 
        } 
        else 
        { 
         Joint primaryHand = GetPrimaryHand(skeleton); 
         TrackHand(primaryHand); 

        } 
       } 
      } 
     } 

     //track and display hand 
     private void TrackHand(Joint hand) 
     { 
      if (hand.TrackingState == JointTrackingState.NotTracked) 
      { 
       kinectButton.Visibility = System.Windows.Visibility.Collapsed; 
      } 
      else 
      { 
       kinectButton.Visibility = System.Windows.Visibility.Visible; 

       DepthImagePoint point = this.Kinect.MapSkeletonPointToDepth(hand.Position, DepthImageFormat.Resolution640x480Fps30); 
       handX = (int)((point.X * LayoutRoot.ActualWidth/this.Kinect.DepthStream.FrameWidth) - 
        (kinectButton.ActualWidth/2.0)); 
       handY = (int)((point.Y * LayoutRoot.ActualHeight/this.Kinect.DepthStream.FrameHeight) - 
        (kinectButton.ActualHeight/2.0)); 
       Canvas.SetLeft(kinectButton, handX); 
       Canvas.SetTop(kinectButton, handY); 

       if (isHandOver(kinectButton, buttons)) kinectButton.Hovering(); 
       else kinectButton.Release(); 
       if (hand.JointType == JointType.HandRight) 
       { 
        kinectButton.ImageSource = "/Images/RightHand.png"; 
        kinectButton.ActiveImageSource = "/Images/RightHand.png"; 
       } 
       else 
       { 
        kinectButton.ImageSource = "/Images/LeftHand.png"; 
        kinectButton.ActiveImageSource = "/Images/LeftHand.png"; 
       } 
      } 
     } 

     //detect if hand is overlapping over any button 
     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; 
     } 

     //get the hand closest to the Kinect sensor 
     private static Joint GetPrimaryHand(Skeleton skeleton) 
     { 
      Joint primaryHand = new Joint(); 
      if (skeleton != null) 
      { 
       primaryHand = skeleton.Joints[JointType.HandLeft]; 
       Joint rightHand = skeleton.Joints[JointType.HandRight]; 
       if (rightHand.TrackingState != JointTrackingState.NotTracked) 
       { 
        if (primaryHand.TrackingState == JointTrackingState.NotTracked) 
        { 
         primaryHand = rightHand; 
        } 
        else 
        { 
         if (primaryHand.Position.Z > rightHand.Position.Z) 
         { 
          primaryHand = rightHand; 
         } 
        } 
       } 
      } 
      return primaryHand; 
     } 

     //get the skeleton closest to the Kinect sensor 
     private static Skeleton GetPrimarySkeleton(Skeleton[] skeletons) 
     { 
      Skeleton skeleton = null; 
      if (skeletons != null) 
      { 
       for (int i = 0; i < skeletons.Length; i++) 
       { 
        if (skeletons[i].TrackingState == SkeletonTrackingState.Tracked) 
        { 
         if (skeleton == null) 
         { 
          skeleton = skeletons[i]; 
         } 
         else 
         { 
          if (skeleton.Position.Z > skeletons[i].Position.Z) 
          { 
           skeleton = skeletons[i]; 
          } 
         } 
        } 
       } 
      } 
      return skeleton; 
     } 

     void kinectButton_Click(object sender, RoutedEventArgs e) 
     { 
      selected.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, selected)); 
     } 

     private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      message.Content = "Button 1 clicked!"; 
     } 

     private void button2_Click(object sender, RoutedEventArgs e) 
     { 
      message.Content = "Button 2 clicked!"; 
     } 

     private void quitButton_Click(object sender, RoutedEventArgs e) 
     { 
      Application.Current.Shutdown(); 
     } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 

     } 
    } 
+0

你想要在輔助窗口中訪問什麼數據? – Lojko 2013-03-15 08:54:34

回答

1

你可以通過幾種不同的方式做到這一點,以及更多的方式,然後下面的內容。

創建時,你可以通過傳感器本身到新窗口的引用:

public MainWindow() 
{ 
    // init code for window and Kinect 

    // show the second window 
    SecondWindow mySecondWindow = new SecondWindow(_Kinect); 
    mySecondWindow.Show(); 

    // other stuff... 
} 

public class SecondWindow : Window 
{ 
    public SecondWindow(KinectSensor sensor) 
    { 
     // ... stuff 

     sensor.SkeletonFrameReady += SkeletonFrameReadyCallback; 

     // ... more stuff 
    } 
} 

然後訂閱SkeletonFrameReady回調在你的第二個窗口。如果您正在與秒窗口交互,這可能適用於您的情況。

另一種方法是在第二個窗口中創建一個公共回調並將其訂閱到SkeletonFrameReady事件。

public MainWindow() 
{ 
    // init code for window and Kinect 

    // show the second window 
    SecondWindow mySecondWindow = new SecondWindow(_Kinect); 
    mySecondWindow.Show(); 

    _Kinect.SkeletonFrameReady += mySecondWindow.SkeletonFrameReadyCallback; 
} 

我也注意到你的代碼中你正在觸發事件。如果您想要在不同窗口的一個窗口中處理事件,則可以訂閱上述相同的自定義事件。

相關問題