1

良い一日ええ。

私はC#プロジェクトに取り組んでおり、Microsoft Kinectを使用して、一連のジャンプを実行する人を追跡し、膝の角度の計算用に生成されたスケルトンを取得します。

昨夜私たちが被験者をテストしていたとき、「現在の」被験者の出力ファイルをクリックして終了し、別の被験者を開始できるようにプログラムを制御できると便利だと思いました。最初にスケルトンを追跡するために、Kinect forWindowsSDKにあるTrackerクラスのトラッカーオブジェクトを作成しました。これにより、追跡と出力を行うすべてのロジックが開始されます。ただし、最初のサブジェクトの出力を「閉じる」と、トラッカーオブジェクトの実際のインスタンスではなく、ファイルを閉じるだけのように見えます。これにより、トラッカーは「開いた」ままになり、新しいテスト対象用に作成したトラッカーオブジェクトの新しいインスタンスと一緒に存在し、2倍の計算リソースを使用して、パフォーマンスの許容できない低下を引き起こします。

トラッカーオブジェクトの最初のインスタンスを「閉じる」にはどうすればよいですか?

調べるためのコードが必要な場合は、私に知らせてください。ここに投稿するのは非現実的に長いので、ここには含めませんでした。

編集:

これが少なくともいくつかのコードです。「開始」イベント(最初の被験者用)、「次の被験者」イベント(後続の被験者用)、および「トラッカー」コードがあります。

次の主題:(これは私たちが変更を加える必要がある主題です)

    /// <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 に答える