none
KinectSensorManager and polling (OpenNextFrame) RRS feed

  • Question

  • Using the sample project, ShapeGame, I am trying to modify it to use polling for the ColorStream instead of events. I am using the latest version of everything (1.5.2)

    I was able to do this successfully until I integrated the KinectSensorManager.
    It now throws an InvalidOperationException when I try do to a ColorStream.OpenNextFrame():
    "This API cannot be called when an event listener has been set."

    Copied directly from ShapeGame:
    MainWindow, KinectSensorManager, and KinectSensorChanged

    InitializeKinectServices is also copied from ShapeGame, but I added a background worker to poll the colorstream.
    I tried commenting out the skeletal stream that was in the shapegame, but still got the same message.
    I looked all through the KinectSensorManager code in the Microsoft.Samples.Kinect.WpfViewers and
    through the KinectSensorChooser code in Microsoft.Kinect.Toolkit to see if a listener was set. I found none.
    What am I missing? It worked without the KinectSensorManager, but then my code crashed as I was trying to test plugging and unplugging the Kinect, so the KinectSensorManager is nice to have. (Plugging and unplugging work perfectly.)

    Here is the relevent code (only 12 lines of code are added to ShapeGame, highlighted in bold):

     private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor)
            {
                // Application should enable all streams first.
                kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30;
                kinectSensorManager.ColorStreamEnabled = true;

                sensor.SkeletonFrameReady += this.SkeletonsReady;
                kinectSensorManager.TransformSmoothParameters = new TransformSmoothParameters
                                                {
                                                    Smoothing = 0.5f,
                                                    Correction = 0.5f,
                                                    Prediction = 0.5f,
                                                    JitterRadius = 0.05f,
                                                    MaxDeviationRadius = 0.04f
                                                };
                kinectSensorManager.SkeletonStreamEnabled = true;
                kinectSensorManager.KinectSensorEnabled = true;

                if (!kinectSensorManager.KinectSensorAppConflict)
                {
                    colorStream = sensor.ColorStream;

                    this.Unloaded += delegate
                    {
                        //do nothing
                    };
                    this.Loaded += delegate
                    {
                        BackgroundWorker bw = new BackgroundWorker();
                        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                        bw.RunWorkerCompleted += (c, d) => bw.RunWorkerAsync(this.colorStream);
                        bw.RunWorkerAsync(this.colorStream);
                    };

                    // Start speech recognizer after KinectSensor started successfully.
                    this.mySpeechRecognizer = SpeechRecognizer.Create();

                    if (null != this.mySpeechRecognizer)
                    {
                        this.mySpeechRecognizer.SaidSomething += this.RecognizerSaidSomething;
                        this.mySpeechRecognizer.Start(sensor.AudioSource);
                    }
                }
            }

            private void bw_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;
                PollColorFrame((ColorImageStream)e.Argument, worker, e);
            }

            private void PollColorFrame(ColorImageStream stream, object sender, DoWorkEventArgs e)
            {
                using (ColorImageFrame imageFrame = stream.OpenNextFrame(colorStreamPollRate))
                ...
            }

    Monday, August 6, 2012 10:59 PM

All replies

  • Can you provide a stack trace for the exception?

    Gary Lewis | Sr. Support Escalation Engineer | Microsoft Windows User Interface Developer Support

    Tuesday, August 7, 2012 3:47 PM
  • This dump is slightly different from the code I used yesterday in that
    RunWorkerAsync gets the KinectSensor instead of KinectSensor.ColorImageStream - same problem though.

    Call stack:
         [External Code]    
    >    MoveRight.exe!MoveRight.MainWindow.PollColorFrame(Microsoft.Kinect.KinectSensor sensor, object sender, System.ComponentModel.DoWorkEventArgs e) Line 1759 + 0x27 bytes    C#
         MoveRight.exe!MoveRight.MainWindow.bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) Line 1751    C#
         [External Code]    


    Exception detail:
    System.InvalidOperationException was unhandled by user code
      Message=This API cannot be called when an event listener has been set.
      Source=Microsoft.Kinect
      StackTrace:
           at Microsoft.Kinect.ColorImageStream.OpenNextFrame(Int32 millisecondsWait)
           at MoveRight.MainWindow.PollColorFrame(KinectSensor sensor, Object sender, DoWorkEventArgs e) in C:\Users\jsnow\Documents\MoveRight Source Code\MoveRight\MainWindow.xaml.cs:line 1759
           at MoveRight.MainWindow.bw_DoWork(Object sender, DoWorkEventArgs e) in C:\Users\jsnow\Documents\MoveRight Source Code\MoveRight\MainWindow.xaml.cs:line 1750
           at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
           at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
      InnerException:

    TaskList:
    Normal    TODO: In multi-proc scenarios, this is getting thrown at the start before we see IOException.  Need to understand.    C:\Program Files\Microsoft SDKs\Kinect\Developer Toolkit v1.5.2\Samples\C#\Microsoft.Kinect.Toolkit\KinectSensorChooser.cs    432

    BTW, to get it to work, all I have to do is avoid binging the KinectSensorManager to the SensorChooseUI in MainWindow, as follows:

                //var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
                //BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding);
                kinectSensor = KinectSensor.KinectSensors[0];
                InitializeKinectServices(kinectSensor);

    And modify InitialKinectServices as follows, which is now called from MainWindow instead of KinectSensorChanged:

                //kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30;
                //kinectSensorManager.ColorStreamEnabled = true;
                //kinectSensorManager.SkeletonStreamEnabled = true;
                //kinectSensorManager.KinectSensorEnabled = true;
                sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                sensor.SkeletonStream.Enable();
                sensor.Start();

    I show the 6 lines I commented out, and the new 5 lines in bold. Unfortunately, without the KinectSensorManager, plugging and unplugging the Kinect doesn't work nearly as well.

    Thanks!

                           
    Tuesday, August 7, 2012 9:47 PM