简体   繁体   中英

WPF application very slow - Kinect SDK 1.7

I have one simple application for Kinect but it seems it consumes a lot of resources. It works normally for a 1-2 minutes and then lag becomes unbearable.

This is my configuration:

Intel Core i3 CPU M330 2.13 GHz

4 GB RAM

ATI Radeon HD 4570

This is code for application window:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;

    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {

        this.WindowState = System.Windows.WindowState.Maximized;
    }

    private void StopKinect(KinectSensor sensor)
    {
        if (sensor != null)
        {
            if (sensor.IsRunning)
            {
                //stop sensor 
                sensor.Stop();

                //stop audio if not null
                if (sensor.AudioSource != null)
                {
                    sensor.AudioSource.Stop();
                }


            }
        }
    }

    private void Window_Closing_1(object sender, System.ComponentModel.CancelEventArgs e)
    {
        StopKinect(Generics.GlobalKinectSensorChooser.Kinect);
    }
}

This is code for main menu (first screen):

public partial class MainMenu : Page
{
    #region "Kinect"
    private KinectSensorChooser sensorChooser;
    #endregion

    public MainMenu()
    {
        this.InitializeComponent();
        if (Generics.GlobalKinectSensorChooser == null)
        {
            // initialize the sensor chooser and UI
            this.sensorChooser = new KinectSensorChooser();
            this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
            this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
            this.sensorChooser.Start();
            Generics.GlobalKinectSensorChooser = this.sensorChooser;
        }
        else
        {   // initialize the sensor chooser and UI 
            this.sensorChooser = new KinectSensorChooser();
            this.sensorChooser = Generics.GlobalKinectSensorChooser;
            this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
            this.sensorChooserUi.KinectSensorChooser = sensorChooser;
        }

        // Bind the sensor chooser's current sensor to the KinectRegion
        var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
        BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);

    }

    private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
    {
        bool error = false;
        if (args.OldSensor != null)
        {
            try
            {
                args.OldSensor.DepthStream.Range = DepthRange.Default;
                args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
                args.OldSensor.DepthStream.Disable();
                args.OldSensor.SkeletonStream.Disable();

                args.OldSensor.ColorStream.Disable();
            }
            catch (InvalidOperationException)
            {
                // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
                // E.g.: sensor might be abruptly unplugged.
                error = true;
            }
        }

        if (args.NewSensor != null)
        {
            try
            {
                args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
                args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                args.NewSensor.SkeletonStream.Enable();
            }
            catch (InvalidOperationException)
            {
                error = true;
            }
        }

        if (!error)
            kinectRegion.KinectSensor = args.NewSensor;
    }

    private void Screen1ButtonOnClick(object sender, RoutedEventArgs e)
    {
        this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
        (Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("Depth.xaml", UriKind.Relative);
    }     
}

And this code for screen1:

public partial class Depth : Page
{
    #region "Kinect"
    private KinectSensorChooser sensorChooser;
    #endregion

    const float MaxDepthDistance = 4095; // max value returned
    const float MinDepthDistance = 850; // min value returned
    const float MaxDepthDistanceOffset = MaxDepthDistance - MinDepthDistance;

    public Depth()
    {

        this.InitializeComponent();
        // initialize the sensor chooser and UI
        this.sensorChooser = new KinectSensorChooser();
        //Assign the sensor chooser with the sensor chooser from the mainwindow. 
        //We are reusing the sensorchoosing declared in the first window that can in contact with kinect
        this.sensorChooser = Generics.GlobalKinectSensorChooser;
        //subscribe to the sensorChooserOnKinectChanged event
        this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
        //Assign Kinect Sensorchooser to the sensorchooser we got from our static class
        this.sensorChooserUi.KinectSensorChooser = sensorChooser;
        // Bind the sensor chooser's current sensor to the KinectRegion
        var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
        BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);
    }

    private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
    {
        bool error = false;
        if (args.OldSensor != null)
        {
            try
            {
                args.OldSensor.DepthStream.Range = DepthRange.Default;
                args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
                args.OldSensor.DepthStream.Disable();
                args.OldSensor.SkeletonStream.Disable();

                args.OldSensor.ColorStream.Disable();
            }
            catch (InvalidOperationException)
            {
                error = true;
            }
        }

        if (args.NewSensor != null)
        {
            try
            {
                args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
                args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                args.NewSensor.SkeletonStream.Enable();

            }
            catch (InvalidOperationException)
            {
                error = true;
            }
        }

        if (!error)
            kinectRegion.KinectSensor = args.NewSensor;
    }


    private void MenuButtonOnClick(object sender, RoutedEventArgs e)
    {
        //Unsubscribe to the sensorchooser's  event SensorChooseronkinectChanged
        this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
        (Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("MainScreen.xaml", UriKind.Relative);
    }
}

There are a couple of more screens, I choosed this screen where I'm using KinectDepthViewer from WpfViewers. This screen has the worst lag, application is unusable almost instantly. Other screens where I have just buttons don't have a lag at the beginning but they get it after 2-3 minutes of usage.

I don't know am I doing something wrong in initialization maybe. I hope someone has some advice. I've read that people didn't have problems with development on even weaker configurations so I hope it's not because of that.

Thank you!

your graphics adapter suggests you're using a notebook computer. While there might be something in your code that could be improved, I really think the problem is your hardware. Notebooks with the specs you listed will have trouble running something as CPU intensive as what you're trying to do with the Kinect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM