1

美好的一天嗯。

我正在做一个 C# 项目,我们使用 Microsoft Kinect,用它来跟踪执行一系列跳跃的人,并获取生成的骨架以计算膝盖角度。

昨晚当我们测试科目时,我认为最好控制程序,您可以单击并结束“当前”测试科目的输出文件,然后开始另一个科目。为了开始跟踪骨架,我们创建了 Kinect for Windows SDK 中的 Tracker 类的跟踪器对象。然后,这将启动执行跟踪和输出的所有逻辑。但是,当我们“关闭”第一个主题的输出时,我们似乎只是在关闭文件,而不是跟踪器对象的实际实例。这会导致跟踪器保持“打开”状态,与我们为新测试对象创建的跟踪器对象的新实例并存,使用双倍的计算资源并导致性能下降到无法接受的程度。

如何“关闭”跟踪器对象的第一个实例?

如果你们需要检查代码,请告诉我;我没有包括它,因为在这里发帖太长了。

编辑:

这里至少有一些代码。我们有“开始”事件(针对第一个测试对象)、“下一个对象”事件(针对后续测试对象)和“跟踪器”代码。

下一个主题:(这是我们需要进行更改的地方)

    /// <summary>
    /// stops "old" file and graph streams, closes file, launches dialog for new subject and starts 
    /// stream up again
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonNextSubject_Click(object sender, RoutedEventArgs e)
    {
        //Ask the user if they're sure they want to stop the current stream
        if (MessageBox.Show("Are you sure you want to stop the stream and start a new one?", "New Subject", MessageBoxButton.OKCancel) == MessageBoxResult.OK){
            if (fileCheck == true)
            {
                tracker.outputFile.closeFiles();
                //SHUT DOWN OLD TRACKER HERE
            }
            else
            {
                return;
            }
        }


        Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
        dlg.FileName = "Subject"; //Default file name
        dlg.DefaultExt = ".txt"; //Default file extension
        dlg.Filter = "Text documents (.txt)|*.txt"; //Filter files by extension
        //Show save file dialog box
        Nullable<bool> result = dlg.ShowDialog();
        buttonStart.IsEnabled = false;
        buttonPause.IsEnabled = true;
        buttonResume.IsEnabled = false;
        fileCheck = true;

        //Start Kinect- If no sensor, ask to connect one and exit.
        try
        {
            this.sensor.Start();
        }
        catch (IOException)
        {
            this.sensor = null;
            //display error message here
            MessageBox.Show("No Kinect sensor found. Please connect one and restart the application", "*****ERROR*****");
        }
        sensor.ElevationAngle = 0;
        tracker = new Tracker(sensor, this, dlg.FileName);
    }
}   

跟踪器对象/跟踪器类:

    internal class Tracker{
        private Skeleton[] skeletons = null;
        private MainWindow window;
        public Class1 outputFile;
        public string fn;
        public Tracker(KinectSensor sensor, MainWindow win, string fileName){                
                //Connect the skeleton frame handler and enable skeleton tracking
                sensor.SkeletonFrameReady += SensorSkeletonFrameReady;
                sensor.SkeletonStream.Enable();
                sensor.ColorFrameReady += SensorColorFrameReady;
                sensor.ColorStream.Enable();
                window = win;                
                outputFile = new Class1(fileName);
                fn = fileName;
                window.graphTickPen2.DashStyle = System.Windows.Media.DashStyles.Dash;
        }

最后,我基于“下一个主题”事件的“开始”事件:

    private void buttonStart_Click(object sender, RoutedEventArgs e){           
        // Configure save file dialog box
        Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
        dlg.FileName = "Default"; // Default file name
        dlg.DefaultExt = ".txt"; // Default file extension
        dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
        // Show save file dialog box
        Nullable<bool> result = dlg.ShowDialog();
        buttonStart.IsEnabled = false;
        buttonPause.IsEnabled = true;
        buttonResume.IsEnabled = false;
        fileCheck = true;
        //Create drawing group
        this.drawingGroup = new DrawingGroup();
        this.leftLegDrawingGroup = new DrawingGroup();
        this.rightLegDrawingGroup = new DrawingGroup();
        //Create image source for WPF control
        this.imageSource = new DrawingImage(this.drawingGroup);
        this.leftLegBoxImageSource = new DrawingImage(this.leftLegDrawingGroup);
        this.rightLegBoxImageSource = new DrawingImage(this.rightLegDrawingGroup);
        leftLegColorBitmap = new WriteableBitmap(483, 152, 96, 96, PixelFormats.Bgr32, null);
        rightLegColorBitmap = new WriteableBitmap(483, 152, 96, 96, PixelFormats.Bgr32, null);
        colorBitmap = new WriteableBitmap(640, 480, 96, 96, PixelFormats.Bgr32, null);
        colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength];           
        //Start Kinect- If no sensor, ask to connect one and exit.
        try{
            this.sensor.Start();
        }
        catch (IOException){
            this.sensor = null;
            //display error message here
            MessageBox.Show("No Kinect sensor found. Please connect one and restart the application", "*****ERROR*****");
        }
        sensor.ElevationAngle = 0;            
        tracker = new Tracker(sensor, this, dlg.FileName);
    }
4

2 回答 2

0

我只听说过.dispose()“终止一个类的实例”,也就是处理它的资源分配。

于 2012-11-09T18:10:36.030 回答
0

窥视 Kinect API 会告诉您,您使用 KinectSensor.Stop() 的方式与您想的完全一样

参考 Kinect API

或者你的问题是这个函数没有做被引用的事情?

编辑:正如我现在理解的问题,您可以像这样从传感器取消订阅跟踪器:

sensor.SkeletonFrameReady -= tracker.SensorSkeletonFrameReady;
sensor.ColorFrameReady -= tracker.SensorColorFrameReady;

您也可以简单地将传感器中的事件设置为 null,这将等于相同(除了它将取消订阅该事件的任何事件处理程序)

sensor.SkeletonFrameReady = null;
sensor.ColorFrameReady = null;

在这个例子中,如果你真的只有跟踪器监听传感器的流,这可能会更容易(因为没有实例化跟踪器时不会出现问题等)

于 2012-11-09T18:15:33.530 回答