UWP Kinect V2 保持帧速率恒定(30fps)

UWP Kinect V2 keep frame rate constant (30fps)

我正在 UWP 中处理从 Kinect v2(彩色和红外)接收的帧。该程序在远程计算机 (XBOX One S) 上运行。主要目标是获取帧并将它们以 30 fps 的速度写入磁盘,用于 Color 和 IR,以便稍后进一步处理它们。

我正在使用以下代码检查帧率:

public MainPage()
{
    this.InitialiseFrameReader(); // initialises MediaCapture for IR and Color
}
    const int COLOR_SOURCE = 0;
    const int IR_SOURCE = 1;

    private async void InitialiseFrameReader()
    {
        await CleanupMediaCaptureAsync();

        var allGroups = await MediaFrameSourceGroup.FindAllAsync();

        if (allGroups.Count == 0)
        {
            return;
        }

        _groupSelectionIndex = (_groupSelectionIndex + 1) % allGroups.Count;
        var selectedGroup = allGroups[_groupSelectionIndex];
        var kinectGroup = selectedGroup;

        try
        {
            await InitializeMediaCaptureAsync(kinectGroup);
        }
        catch (Exception exception)
        {
            _logger.Log($"MediaCapture initialization error: {exception.Message}");
            await CleanupMediaCaptureAsync();
            return;
        }

        // Set up frame readers, register event handlers and start streaming.
        var startedKinds = new HashSet<MediaFrameSourceKind>();
        foreach (MediaFrameSource source in _mediaCapture.FrameSources.Values.Where(x => x.Info.SourceKind == MediaFrameSourceKind.Color || x.Info.SourceKind == MediaFrameSourceKind.Infrared)) //
        {
            MediaFrameSourceKind kind = source.Info.SourceKind;
            MediaFrameSource frameSource = null;

            int frameindex = COLOR_SOURCE;
            if (kind == MediaFrameSourceKind.Infrared)
            {
                frameindex = IR_SOURCE;
            }
            // Ignore this source if we already have a source of this kind.
            if (startedKinds.Contains(kind))
            {
                continue;
            }
            MediaFrameSourceInfo frameInfo = kinectGroup.SourceInfos[frameindex];
            if (_mediaCapture.FrameSources.TryGetValue(frameInfo.Id, out frameSource))
            {
                // Create a frameReader based on the source stream
                MediaFrameReader frameReader = await _mediaCapture.CreateFrameReaderAsync(frameSource);

                frameReader.FrameArrived += FrameReader_FrameArrived;
                _sourceReaders.Add(frameReader);

                MediaFrameReaderStartStatus status = await frameReader.StartAsync();
                if (status == MediaFrameReaderStartStatus.Success)
                {
                    startedKinds.Add(kind);
                }
                
            }
        }
    }

    private async Task InitializeMediaCaptureAsync(MediaFrameSourceGroup sourceGroup)
    {
        if (_mediaCapture != null)
        {
            return;
        }

        // Initialize mediacapture with the source group.
        _mediaCapture = new MediaCapture();
        var settings = new MediaCaptureInitializationSettings
        {
            SourceGroup = sourceGroup,

            SharingMode = MediaCaptureSharingMode.SharedReadOnly,

            StreamingCaptureMode = StreamingCaptureMode.Video,

            MemoryPreference = MediaCaptureMemoryPreference.Cpu
        };
        await _mediaCapture.InitializeAsync(settings);
    }


private void FrameReader_FrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
        {          
            using (var frame = sender.TryAcquireLatestFrame())
            {
                if (frame != null)
                {    


                //Settings.cameraframeQueue.Enqueue(null, frame.SourceKind.ToString(), frame.SystemRelativeTime.Value); //Add to Queue to process frame 
                Debug.WriteLine(frame.SourceKind.ToString() + " : " + frame.SystemRelativeTime.ToString());         
            }
        }
    }

我正在尝试调试应用程序以检查帧速率,因此我删除了进一步的处理。

不知道是我计算的不对还是其他什么地方不对。

例如,从 04:37:06 到 04:37:48 的系统相对时间给出:

IR: Fps(发生)

31(1) 30(36) 29(18) 28(4)

颜色: Fps(发生)

30(38) 29(18) 28(3)

我希望此帧速率保持恒定 (30 fps) 并对齐,以便 IR 和颜色以及当时相同的帧数。

这不包括任何附加代码。一旦我有了进程队列或任何类型的代码,fps 就会下降,范围从 15 到 30。

谁能帮我解决这个问题?

谢谢。

更新:

经过一些测试和变通后,我注意到 PC 产生 30fps 但 XBOX One(远程设备)在调试模式下产生非常低的 fps。然而,当 运行 它处于发布模式但分配给 UWP 应用程序的内存非常低时,这确实会有所改善。 https://docs.microsoft.com/en-us/windows/uwp/xbox-apps/system-resource-allocation

Xbox One 的最大可用内存为 1 GB 用于应用程序,5 GB 用于游戏。 https://docs.microsoft.com/en-us/windows/uwp/xbox-apps/system-resource-allocation

而在 PC 中 fps 是 30(因为内存没有这样的限制)。

这会导致帧率下降。但是,当 运行 在发布模式下或发布到 MS Store 时,fps 确实有所提高。