2012-12-13 43 views
3

這是我第一次試圖做一個使用Kinect的程序,我不知道爲什麼我一直得到一個null錯誤。也許有人更好地瞭解KinectSDK可以提供幫助?Kinect錯誤啓用流

public ProjKinect() 
{ 
    InitializeComponent(); 
    updateSensor(0);//set current sensor as 0 since we just started 
} 

public void updateSensor(int sensorI) 
{ 
    refreshSensors();//see if any new ones connected 
    if (sensorI >= sensors.Length)//if it goes to end, then repeat 
    { 
     sensorI = 0; 
    } 
    currentSensorInt = sensorI; 
    if (activeSensor != null && activeSensor.IsRunning) 
    { 
     activeSensor.Stop();//stop so we can cahnge 
    } 
    MessageBox.Show(sensors.Length + " Kinects Found"); 
    activeSensor = KinectSensor.KinectSensors[currentSensorInt]; 
    activeSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30); //ERROR IS RIGHT HERE 
    activeSensor.DepthStream.Enable(); 
    activeSensor.SkeletonStream.Enable(); 
    activeSensor.SkeletonFrameReady += runtime_SkeletonFrameReady; 
    activeSensor.DepthFrameReady += runtime_DepthFrameReady; 
    activeSensor.ColorFrameReady += runtime_ImageFrameReady; 
    activeSensor.Start();//start the newly enabled one 
} 
public void refreshSensors() 
{ 
    sensors = KinectSensor.KinectSensors.ToArray(); 
} 

錯誤:

Object reference not set to an instance of an object. 

順便說一句,它說我有1 Kinect的連接,所以我知道它至少承認,我有事情來連接。如果我只是說0而不是currentSensorInt,它也不起作用。如果我將ColorStream.Enable評論爲DepthStream.Enable,也是一個錯誤。所以我猜測我創建傳感器時只是做錯了什麼?

希望它有點小。 在此先感謝:)

回答

3

我沒有看到任何明顯的錯誤,但我也沒有看到傳感器獲取和設置完全按照這種方式。你有看過Kinect for Windows Developer Toolkit的例子嗎?有多個如何連接到Kinect的例子,有些只是暴力連接,而另一些則非常強大。

例如,這是從SlideshowGestures-WPF例如連接碼的修剪版本:

public partial class MainWindow : Window 
{ 
    /// <summary> 
    /// Active Kinect sensor 
    /// </summary> 
    private KinectSensor sensor; 

    /// <summary> 
    /// Execute startup tasks 
    /// </summary> 
    /// <param name="sender">object sending the event</param> 
    /// <param name="e">event arguments</param> 
    private void WindowLoaded(object sender, RoutedEventArgs e) 
    { 
     // Look through all sensors and start the first connected one. 
     // This requires that a Kinect is connected at the time of app startup. 
     // To make your app robust against plug/unplug, 
     // it is recommended to use KinectSensorChooser provided in Microsoft.Kinect.Toolkit 
     foreach (var potentialSensor in KinectSensor.KinectSensors) 
     { 
      if (potentialSensor.Status == KinectStatus.Connected) 
      { 
       this.sensor = potentialSensor; 
       break; 
      } 
     } 

     if (null != this.sensor) 
     { 
      // Turn on the color stream to receive color frames 
      this.sensor.ColorStream.Enable(ColorImageFormat.InfraredResolution640x480Fps30); 

      // Add an event handler to be called whenever there is new color frame data 
      this.sensor.ColorFrameReady += this.SensorColorFrameReady; 

      // Start the sensor! 
      try 
      { 
       this.sensor.Start(); 
      } 
      catch (IOException) 
      { 
       this.sensor = null; 
      } 
     } 
    } 

    /// <summary> 
    /// Execute shutdown tasks 
    /// </summary> 
    /// <param name="sender">object sending the event</param> 
    /// <param name="e">event arguments</param> 
    private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     if (null != this.sensor) 
     { 
      this.sensor.Stop(); 
     } 
    } 
} 

得到的傳感器雖然最簡單的方法是使用KinectSensorChooser類,它是部分Microsoft.Kinect.Toolkit命名空間。它爲你做所有的工作。例如,以下是我的設置的修剪版本:

public class MainViewModel : ViewModelBase 
{ 
    private readonly KinectSensorChooser _sensorChooser = new KinectSensorChooser(); 

    /// <summary> 
    /// Initializes a new instance of the MainViewModel class. 
    /// </summary> 
    public MainViewModel(IDataService dataService) 
    { 
     if (IsInDesignMode) 
     { 
      // do something special, only for design mode 
     } 
     else 
     { 
      _sensorChooser.Start(); 

      if (_sensorChooser.Kinect == null) 
      { 
       MessageBox.Show("Unable to detect an available Kinect Sensor"); 
       Application.Current.Shutdown(); 
      } 
     } 
    } 

就是這樣。我有一個傳感器,我可以開始使用它。我如何連接和控制的Kinect的更大的示例使用從工具包中的KinectSensorManager類,這是在KinectWpfViewers命名空間:

public class MainViewModel : ViewModelBase 
{ 
    private readonly KinectSensorChooser _sensorChooser = new KinectSensorChooser(); 

    /// <summary> 
    /// Initializes a new instance of the MainViewModel class. 
    /// </summary> 
    public MainViewModel(IDataService dataService) 
    { 
     if (IsInDesignMode) 
     { 
      // do something special, only for design mode 
     } 
     else 
     { 
      KinectSensorManager = new KinectSensorManager(); 
      KinectSensorManager.KinectSensorChanged += OnKinectSensorChanged; 

      _sensorChooser.Start(); 

      if (_sensorChooser.Kinect == null) 
      { 
       MessageBox.Show("Unable to detect an available Kinect Sensor"); 
       Application.Current.Shutdown(); 
      } 

      // Bind the KinectSensor from the sensorChooser to the KinectSensor on the KinectSensorManager 
      var kinectSensorBinding = new Binding("Kinect") { Source = _sensorChooser }; 
      BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding); 
     } 
    } 

    #region Kinect Discovery & Setup 

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

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

    /// <summary> 
    /// Initialize Kinect based services. 
    /// </summary> 
    /// <param name="kinectSensorManager"></param> 
    /// <param name="sensor"></param> 
    private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor) 
    { 
     // configure the color stream 
     kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30; 
     kinectSensorManager.ColorStreamEnabled = true; 

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

     kinectSensorManager.TransformSmoothParameters = 
      new TransformSmoothParameters 
      { 
       // as the smoothing value is increased responsiveness to the raw data 
       // decreases; therefore, increased smoothing leads to increased latency. 
       Smoothing = 0.5f, 
       // higher value corrects toward the raw data more quickly, 
       // a lower value corrects more slowly and appears smoother. 
       Correction = 0.5f, 
       // number of frames to predict into the future. 
       Prediction = 0.5f, 
       // determines how aggressively to remove jitter from the raw data. 
       JitterRadius = 0.05f, 
       // maximum radius (in meters) that filtered positions can deviate from raw data. 
       MaxDeviationRadius = 0.04f 
      }; 

     // configure the skeleton stream 
     sensor.SkeletonFrameReady += OnSkeletonFrameReady; 
     kinectSensorManager.SkeletonStreamEnabled = true; 

     // initialize the gesture recognizer 
     _gestureController = new GestureController(); 
     _gestureController.GestureRecognized += OnGestureRecognized; 

     kinectSensorManager.KinectSensorEnabled = true; 

     if (!kinectSensorManager.KinectSensorAppConflict) 
     { 
      // set up addition Kinect based services here 
      // (e.g., SpeechRecognizer) 
     } 

     kinectSensorManager.ElevationAngle = Settings.Default.KinectAngle; 
    } 

    /// <summary> 
    /// Uninitialize all Kinect services that were initialized in InitializeKinectServices. 
    /// </summary> 
    /// <param name="sensor"></param> 
    private void UninitializeKinectServices(KinectSensor sensor) 
    { 
     sensor.SkeletonFrameReady -= this.OnSkeletonFrameReady; 
    } 

    #endregion Kinect Discovery & Setup 

    #region Properties 

    public KinectSensorManager KinectSensorManager { get; private set; } 

    #endregion Properties 
} 

的所有這些額外的代碼的優點是可以在KinectExplorer例如,在工具箱中可以看出。簡而言之 - 我可以使用此代碼管理多個Kinect,拔出一個Kinect,然後程序切換到另一個Kinect。

+0

感謝您的回答。但不知何故,它在很多時候拔出並插入kinect後纔開始工作。猜測這只是一個奇怪的故障,因爲它現在起作用。感謝所有的示例代碼。絕對幫助我掌握SDK。 – Brandon

+1

是的,發生了。我還沒弄明白爲什麼。您有時會在'Kinect.dll'中得到一個「InvalidOperation」異常 - 當您拔下Kinect並重新插入時通常會解決這個異常。在調試時保持輸出窗口打開,以確保您可以觀察此異常以瞭解當你需要拔掉東西。 :) –