2012-12-03 151 views
1

我一直在使用SDK v1.5和VS2012使Kinect For Windows的骨架跟蹤正常工作時遇到了一些麻煩。我正在構建來自https://github.com/EvilClosetMonkey/Fizbin.Kinect.Gestures的源代碼,但當屏幕上有多個人時,跟蹤會完全誤入歧途。然後我轉眼就來看看這裏的代碼(http://social.msdn.microsoft.com/Forums/en-US/kinectsdknuiapi/thread/459012d7-d51e-460d-aa6a-a1b80c27626c/),我已經嘗試整合「AppChoosesSkeletons」功能(下面的代碼):C#Kinect骨架跟蹤

using System.Windows; 
using System.Windows.Data; 
using Microsoft.Kinect; 
using Microsoft.Kinect.Toolkit; 
using Microsoft.Samples.Kinect.WpfViewers; 
using System.Diagnostics; 
using System.ComponentModel; 
using System.Linq; 
using System; 

namespace Fizbin.Kinect.Gestures.Demo 
{ 
public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    private readonly KinectSensorChooser sensorChooser = new KinectSensorChooser(); 

    private Skeleton[] skeletons = new Skeleton[0]; 

    // skeleton gesture recognizer 
    private GestureController gestureController; 

    public MainWindow() 
    { 
     DataContext = this; 

     InitializeComponent(); 

     // initialize the Kinect sensor manager 
     KinectSensorManager = new KinectSensorManager(); 
     KinectSensorManager.KinectSensorChanged += this.KinectSensorChanged; 

     // locate an available sensor 
     sensorChooser.Start(); 

     // bind chooser's sensor value to the local sensor manager 
     var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser }; 
     BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding); 
    } 

    #region Kinect Discovery & Setup 

    private void KinectSensorChanged(object sender, KinectSensorManagerEventArgs<KinectSensor> args) 
    { 
     if (null != args.OldValue) 
      UninitializeKinectServices(args.OldValue); 

     if (null != args.NewValue) 
      InitializeKinectServices(KinectSensorManager, args.NewValue); 
    } 

    /// <summary> 
    /// Kinect enabled apps should customize which Kinect services it initializes here. 
    /// </summary> 
    /// <param name="kinectSensorManager"></param> 
    /// <param name="sensor"></param> 
    private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor) 
    { 
     // Application should enable all streams first. 

     // configure the color stream 
     kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30; 
     kinectSensorManager.ColorStreamEnabled = true; 

     // configure the depth stream 
     kinectSensorManager.DepthStreamEnabled = true; 

     kinectSensorManager.TransformSmoothParameters = 
      new TransformSmoothParameters 
      { 
       Smoothing = 0.5f, 
       Correction = 0.5f, 
       Prediction = 0.5f, 
       JitterRadius = 0.05f, 
       MaxDeviationRadius = 0.04f 
      }; 

     // configure the skeleton stream 
     sensor.SkeletonFrameReady += FramesReady; 
     kinectSensorManager.SkeletonStreamEnabled = true; 
     sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated; 
     // initialize the gesture recognizer 
     gestureController = new GestureController(); 
     gestureController.GestureRecognized += OnGestureRecognized; 

     kinectSensorManager.KinectSensorEnabled = true; 

     if (!kinectSensorManager.KinectSensorAppConflict) 
     { 
      // addition configuration, as needed 
     } 
    } 

    /// <summary> 
    /// Kinect enabled apps should uninitialize all Kinect services that were initialized in InitializeKinectServices() here. 
    /// </summary> 
    /// <param name="sensor"></param> 
    private void UninitializeKinectServices(KinectSensor sensor) 
    { 

    } 

    #endregion Kinect Discovery & Setup 

    #region Properties 

    public static readonly DependencyProperty KinectSensorManagerProperty = 
     DependencyProperty.Register(
      "KinectSensorManager", 
      typeof(KinectSensorManager), 
      typeof(MainWindow), 
      new PropertyMetadata(null)); 

    public KinectSensorManager KinectSensorManager 
    { 
     get { return (KinectSensorManager)GetValue(KinectSensorManagerProperty); } 
     set { SetValue(KinectSensorManagerProperty, value); } 
    } 

    /// <summary> 
    /// Gets or sets the last recognized gesture. 
    /// </summary> 
    private string _gesture; 
    public String Gesture 
    { 
     get { return _gesture; } 

     private set 
     { 
      if (_gesture == value) 
       return; 

      _gesture = value; 

      Debug.WriteLine("Gesture = " + _gesture); 

      if (this.PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("Gesture")); 
     } 
    } 

    #endregion Properties 

    #region Events 

    /// <summary> 
    /// Event implementing INotifyPropertyChanged interface. 
    /// </summary> 
    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion Events 

    #region Event Handlers 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e">Gesture event arguments.</param> 
    private void OnGestureRecognized(object sender, GestureEventArgs e) 
    { 
     Debug.WriteLine(e.GestureType); 

     switch (e.GestureType) 
     { 
      case GestureType.Menu: 
       Gesture = "Menu"; 
       break; 
      case GestureType.WaveRight: 
       Gesture = "Wave Right"; 
       break; 
      case GestureType.WaveLeft: 
       Gesture = "Wave Left"; 
       break; 
      case GestureType.JoinedHands: 
       Gesture = "Joined Hands"; 
       break; 
      case GestureType.SwipeLeft: 
       Gesture = "Swipe Left"; 
       break; 
      case GestureType.SwipeRight: 
       Gesture = "Swipe Right"; 
       break; 
      case GestureType.ZoomIn: 
       Gesture = "Zoom In"; 
       break; 
      case GestureType.ZoomOut: 
       Gesture = "Zoom Out"; 
       break; 

      default: 
       break; 
     } 
    } 

    void FramesReady(object sender, AllFramesReadyEventArgs e, KinectSensor sensor) 
    { 
     Skeleton skeleton = FindSkeleton(e); 
     if (skeleton != null) 
     { 
      gestureController.UpdateAllGestures(skeleton); 
     } 
    } 

    private int CurrentTrackingId = 0; 

    Skeleton FindSkeleton(AllFramesReadyEventArgs e) 
    { 
     Skeleton skeleton = null; 

     using (SkeletonFrame SFrame = e.OpenSkeletonFrame()) 
     { 
      if (SFrame == null) 
      { 
       return null; 
      } 

      if (skeletons == null) 
      { 
       skeletons = new Skeleton[SFrame.SkeletonArrayLength]; 
      } 

      SFrame.CopySkeletonDataTo(skeletons); 

      if (CurrentTrackingId != 0) 
      { 
       // We've been tracking someone; see if they're still here 

       skeleton = 
        (from s in skeletons 
        where s.TrackingState == SkeletonTrackingState.Tracked && 
          s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked && 
          s.TrackingId == CurrentTrackingId 
        select s).FirstOrDefault(); 

       if (skeleton == null) 
       { 
        CurrentTrackingId = 0; 
        sensor.SkeletonStream.AppChoosesSkeletons = false; 
       } 
      } 
      else 
      { 
       // Try to find someone new 

       skeleton = 
        (from s in skeletons 
        where s.TrackingState == SkeletonTrackingState.Tracked && 
          s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked 
        select s).FirstOrDefault(); 

       if (skeleton != null) 
       { 
        CurrentTrackingId = skeleton.TrackingId; 
        sensor.SkeletonStream.AppChoosesSkeletons = true; 
        sensor.SkeletonStream.ChooseSkeletons(CurrentTrackingId); 
       } 
      } 
     } 

     return skeleton; 
    } 

    #endregion Event Handlers 

    } 
} 

從VS2012約然而,遇到錯誤:

1)無過載爲「FramesReady」匹配委託「System.EventHandler」

2)「傳感器」,由於它沒有被導入不存在的(最有可能的,但是從我已經試過,路過橫跨傳感器的傳感器會導致更多錯誤)

如果有人能夠幫助解決這個問題,或者甚至指出我解決這個問題的正確方向,那會很棒!重申一下,主要目標是將Kinect鎖定到找到的第一個人,並鎖定多人在視線中移動。

回答

1

如果您打算繼續使用KinectSensorManager,則可以使用KinectSkeletonChooser來幫助您挑選出所需的骨架。該幫助功能也包含在KinectWpfViewers項目中。爲了使用它,您不需要向後面的代碼添加任何附加代碼。

最簡單的方法就是將其添加到您的XAML中。更新附帶的除星期二庫中的演示代碼,它看起來像日:

<Window x:Class="Fizbin.Kinect.Gestures.Demo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:kv="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid>   
     <Grid HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="320" Height="240"> 
      <kv:KinectSkeletonChooser KinectSensorManager="{Binding KinectSensorManager}" SkeletonChooserMode="Sticky1Player" /> 
      <kv:KinectDepthViewer x:Name="DepthViewer" KinectSensorManager="{Binding KinectSensorManager}" /> 
      <Canvas> 
       <kv:KinectSkeletonViewer 
            KinectSensorManager="{Binding KinectSensorManager}" 
            Width="{Binding ElementName=DepthViewer, Path=ActualWidth}" 
            Height="{Binding ElementName=DepthViewer, Path=ActualHeight}" 
            ShowBones="True" ShowJoints="True" ShowCenter="True" ImageType="Depth" /> 
      </Canvas> 
     </Grid> 

     <TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="-2,0,0,0"/> 
     <TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="2,0,0,0"/> 
     <TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="0,-2,0,0"/> 
     <TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="0,2,0,0"/> 
     <TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Foreground="White"/> 

    </Grid> 
</Window> 

注新KinectSkeletonChooser標籤上線8

其他可用選項可以在待見SkeletonChooserMode enum:

public enum SkeletonChooserMode 
{ 
    /// <summary> 
    /// Use system default tracking 
    /// </summary> 
    DefaultSystemTracking, 

    /// <summary> 
    /// Track the player nearest to the sensor 
    /// </summary> 
    Closest1Player, 

    /// <summary> 
    /// Track the two players nearest to the sensor 
    /// </summary> 
    Closest2Player, 

    /// <summary> 
    /// Track one player based on id 
    /// </summary> 
    Sticky1Player, 

    /// <summary> 
    /// Track two players based on id 
    /// </summary> 
    Sticky2Player, 

    /// <summary> 
    /// Track one player based on most activity 
    /// </summary> 
    MostActive1Player, 

    /// <summary> 
    /// Track two players based on most activity 
    /// </summary> 
    MostActive2Player 
} 
+0

非常好,謝謝!當我有機會時,我會給它一個機會,並報告它是否有效! – RyanW