如何解决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 举报,一经查实,本站将立刻删除。