1

私はKinectを初めて使用します。スケルトン トラッキングを使用しようとしていますが、「警告: ImageFrame インスタンスが破棄されませんでした。」という警告が表示され続けました。その解決策を知っていますか?

これが私のコードです

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
using System.Diagnostics;
using System.IO;

namespace KinectSkeleton
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        bool closing = false;
        const int skeletonCount = 6;
        Skeleton[] allSkeletons = new Skeleton[skeletonCount];

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            myKinectSensorChooser.KinectSensorChanged += new DependencyPropertyChangedEventHandler(myKinectSensorChooser_KinectSensorChanged);
        }

        void myKinectSensorChooser_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor oldSensor = (KinectSensor)e.OldValue;
            if (oldSensor != null)
            {
                oldSensor.Stop();
                oldSensor.AudioSource.Stop();
            }

            KinectSensor mySensor = (KinectSensor)e.NewValue;
            if (mySensor == null)
                return;

            mySensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
            mySensor.ColorStream.Enable();
            mySensor.SkeletonStream.Enable();
            mySensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(mySensor_AllFramesReady);

            try
            {
                mySensor.Start();
                Debug.WriteLine("Starting Sensor .....");
                Debug.WriteLine("The Current Elevation Angle is: " + mySensor.ElevationAngle.ToString());
                mySensor.ElevationAngle = 0;
            }
            catch (System.IO.IOException)
            {
                //another app is using Kinect
                myKinectSensorChooser.AppConflictOccurred();
            }
        }

        void mySensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (closing)
                return;

            byte[] depthImagePixels;
            DepthImageFrame depthFrame = e.OpenDepthImageFrame();
            if (depthFrame == null)
                return;

            depthImagePixels = GenerateDepthImage(depthFrame);
            int stride = depthFrame.Width*4;
            image1.Source =
                BitmapSource.Create(depthFrame.Width, depthFrame.Height,
                96, 96, PixelFormats.Bgr32, null, depthImagePixels, stride);


            //Get a skeleton
            Skeleton first = GetFirstSkeleton(e);
            if (first == null)
                return;

            Debug.WriteLine("Head Position is : " + first.Joints[JointType.Head].ToString());

            depthFrame.Dispose();

        }

        private byte[] GenerateDepthImage(DepthImageFrame depthFrame)
        {
            //get the raw data from the frame with the depth for every pixel
            short[] rawDepthData = new short[depthFrame.PixelDataLength];
            depthFrame.CopyPixelDataTo(rawDepthData);

            //use frame to create the image to display on-screen
            //frame contains color information for all pixels in image
            //Height x Width x 4 (Red, Green, Blue, empty byte)
            Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];

            //hardcoded locations to Blue, Green, Red (BGR) index positions       
            const int BlueIndex = 0;
            const int GreenIndex = 1;
            const int RedIndex = 2;
            int player, depth;

            //loop through all distances
            //pick a RGB color based on distance
            for (int depthIndex = 0, colorIndex = 0;
                depthIndex < rawDepthData.Length && colorIndex < pixels.Length;
                depthIndex++, colorIndex += 4)
            {
                //get the player (requires skeleton tracking enabled for values)
                player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;

                //gets the depth value
                depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;

                if (player > 0)
                {
                    pixels[colorIndex + BlueIndex] = Colors.Gold.B;
                    pixels[colorIndex + GreenIndex] = Colors.Gold.G;
                    pixels[colorIndex + RedIndex] = Colors.Gold.R;
                }
                else
                {
                    pixels[colorIndex + BlueIndex] = Colors.Green.B;
                    pixels[colorIndex + GreenIndex] = Colors.Green.G;
                    pixels[colorIndex + RedIndex] = Colors.Green.R;
                }
            }
            //depthFrame.Dispose();
            return pixels;
        }

        Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
        {
            using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
            {
                if (skeletonFrameData == null)
                {
                    return null;
                }
                skeletonFrameData.CopySkeletonDataTo(allSkeletons);

                //get the first tracked skeleton
                Skeleton first = (from s in allSkeletons
                                  where s.TrackingState == SkeletonTrackingState.Tracked
                                  select s).FirstOrDefault();

                return first;
            }
        }

        void StopKinect(KinectSensor sensor)
        {
            if (sensor != null)
            {
                if (sensor.IsRunning)
                {
                    sensor.ElevationAngle = 0;
                    sensor.Stop();
                    if (sensor.AudioSource != null)
                    {
                        sensor.AudioSource.Stop();
                    }
                }
            }
        }
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            closing = true;
            Debug.WriteLine("Closing window...");
            StopKinect(myKinectSensorChooser.Kinect);
        }
    }
}

どうもありがとう、マイケル

4

1 に答える 1

4

あなたが書いたメソッドmySensor_AllFramesReadyで

       //Get a skeleton
        Skeleton first = GetFirstSkeleton(e);
        if (first == null)
            return; // Here if first skeleton is null then you are returning without disposing depthFrame frame.

以下のように深度フレームを開きながらブロックを使用して使用します

  using(DepthImageFrame depthFrame = e.OpenDepthImageFrame())
  {
        if (depthFrame == null)
            return;

        depthImagePixels = GenerateDepthImage(depthFrame);
        int stride = depthFrame.Width*4;
        image1.Source =
            BitmapSource.Create(depthFrame.Width, depthFrame.Height,
            96, 96, PixelFormats.Bgr32, null, depthImagePixels, stride);


        //Get a skeleton
        Skeleton first = GetFirstSkeleton(e);
        if (first == null)
            return;

        Debug.WriteLine("Head Position is : " + first.Joints[JointType.Head].ToString());
     }
于 2012-05-21T10:40:29.203 に答える