【问题标题】:Kinect 2 fast handle frames -> low fps rateKinect 2 快速处理帧 -> 低 fps 速率
【发布时间】:2015-04-01 11:11:13
【问题描述】:

当我使用kinect 2的示例颜色基础并以毫秒为单位计算每个图像之间的时间时,通常在30ms左右,但是当我将函数图像事件的内部代码更改为注释时,帧之间的时间是:

34,231,32,33,134,32,266,32,33,172,67,166,28,64,33,101,32,33,34,32,32,138,94,32,26

等等(低于 20 fps)。

我的电脑使用 i7(8 次治愈), cpu 仅 6%,8GB 内存.. 所以这不是问题。

相关代码:

public partial class MainWindow : Window, INotifyPropertyChanged
    {
        /// <summary>
        /// Active Kinect sensor
        /// </summary>
        private KinectSensor kinectSensor = null;

        /// <summary>
        /// Reader for color frames
        /// </summary>
        private ColorFrameReader colorFrameReader = null;

        /// <summary>
        /// Bitmap to display
        /// </summary>
        private WriteableBitmap colorBitmap = null;

        /// <summary>
        /// Current status text to display
        /// </summary>
        private string statusText = null;

        /// <summary>
        /// Initializes a new instance of the MainWindow class.
        /// </summary>
        public MainWindow()
        {
            // get the kinectSensor object
            this.kinectSensor = KinectSensor.GetDefault();

            // open the reader for the color frames
            this.colorFrameReader = this.kinectSensor.ColorFrameSource.OpenReader();

            // wire handler for frame arrival
            this.colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;

            // create the colorFrameDescription from the ColorFrameSource using Bgra format
            FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);

            // create the bitmap to display
            this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);

            // set IsAvailableChanged event notifier
            this.kinectSensor.IsAvailableChanged += this.Sensor_IsAvailableChanged;

            // open the sensor
            this.kinectSensor.Open();

            // set the status text
            this.StatusText = this.kinectSensor.IsAvailable ? Properties.Resources.RunningStatusText
                                                            : Properties.Resources.NoSensorStatusText;

            // use the window object as the view model in this simple example
            this.DataContext = this;

            // initialize the components (controls) of the window
            this.InitializeComponent();

            sw.Start();
        }

        Stopwatch sw = new Stopwatch();
        /// <summary>
        /// Handles the color frame data arriving from the sensor
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
        {
            System.Console.WriteLine(sw.ElapsedMilliseconds);
            sw.Restart();
            // ColorFrame is IDisposable

            // Changed into comment here:

            /*using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
            {
                if (colorFrame != null)
                {
                    FrameDescription colorFrameDescription = colorFrame.FrameDescription;

                    using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
                    {
                        this.colorBitmap.Lock();

                        // verify data and write the new color frame data to the display bitmap
                        if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
                        {
                            colorFrame.CopyConvertedFrameDataToIntPtr(
                                this.colorBitmap.BackBuffer,
                                (uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
                                ColorImageFormat.Bgra);

                            this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                        }

                        this.colorBitmap.Unlock();
                    }
                }
            }*/
        }
    }

为什么会这样以及如何解决?

【问题讨论】:

  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
  • Console.WriteLine 不适用于高性能代码。尝试添加一个计数器并使用 if( frameCounter++ % 10 == 0) Console.WriteLine 每隔 10 帧打印一次
  • WriteLine 不是时间计算的一​​部分并使用了这两种情况,我检查了帧之间的时间(应该是~30ms)然后我才打印它,打印后重新启动时间,请看我的回答需要“花费”足够的时间才能及时获得下一帧。
  • 也许问题在于,如果您注释该函数,您不会调用 e.FrameReference.AcquireFrame(),它会将帧留在队列中。我现在无法尝试,请自行检查。尝试只保留对 e.FrameReference.AcquireFrame() 的调用(以及对 .Dispose() 的相应调用)未注释。

标签: c# kinect frame-rate


【解决方案1】:

当我在此功能上“花费”足够的时间时,它可以完美运行,例如:

for (int i = 0 ; i < 1000000; i++);

我不记得我是使用 1 mil 还是 10 mil 迭代的循环(这取决于计算机),但使用后我几乎总是每 30 毫秒获得一次帧。

这看起来像是微软在 kinect 2 上的一个错误,这是他们最后一个 sdk 版本 - 2.0(这是他们的第一个)。

注意:使用thread.sleap 不会修复它。

所以现在解决方案(但非常糟糕)是检查运行时间(如果它太快)并在需要时花费时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多