微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决UWP Kinect V2 保持帧速率恒定 (30fps)

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

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

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 给出:

红外: 每秒帧数(发生次数

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

颜色: 每秒帧数(发生次数

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

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

这不包括任何额外的代码。只要我有进程队列或任何类型的代码,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 确实有所提高。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。