【发布时间】:2010-10-28 11:58:21
【问题描述】:
问题是:我有一个自定义硬件设备,我必须在 C#/WPF 中从中获取图像并将它们显示在一个窗口中,所有这些都具有 120+ FPS。
问题是没有事件表明图像准备好了,但我必须不断地轮询设备并检查是否有任何新图像然后下载它们。
显然有几种方法可以做到这一点,但我还没有找到合适的方法。
这是我尝试过的:
一个简单的计时器(或 DispatcherTimer) - 适用于较慢的帧速率,但我无法超过 60 FPS。
单线程无限循环 - 相当快,但我必须将 DoEvents/它的 WPF 等效项放入循环中,以便重绘窗口;这会产生一些其他不需要的(奇怪)后果,例如某些控件未触发的按键事件等。
-
在另一个线程中进行轮询/下载并在 UI 线程中显示,如下所示:
new Thread(() => { while (StillCapturing) { if (Camera.CheckForAndDownloadImage(CameraInstance)) { this.Dispatcher.Invoke((Action)this.DisplayImage); } } }).Start();嗯,这工作得比较好,但是会给 CPU 带来相当大的负载,如果机器没有超过一个 CPU/内核,当然会完全杀死机器,这是不可接受的。另外,我这种方式有大量的线程争用。
问题很明显 - 有没有更好的选择,或者在这种情况下可以采用其中一种方法吗?
更新:
我不知何故忘了提到这一点(好吧,写这个问题时忘了考虑它),但我当然不需要显示 all 帧,但我仍然需要捕获所有帧所以它们可以保存到硬盘上。
更新 2: 我发现 DispatcherTimer 方法慢不是因为它不能足够快地处理所有事情,而是因为 DispatcherTimer 在触发滴答事件之前等待下一次垂直同步;在我的情况下这实际上很好,因为在滴答事件中我可以将所有待处理的图像保存到内存缓冲区(用于将图像保存到磁盘)并只显示最后一个。
至于被捕获完全“杀死”的旧计算机,WPF 似乎退回到非常慢的软件渲染。我可能无能为力。
感谢大家的回答。
【问题讨论】:
-
120+ FPS?您使用哪种显示技术作为我的 TFT 显示器(高清)不会真正超过 60Hz,因此无论如何它都会丢失一半的帧。
-
谢谢。你是绝对正确的。不知道我是怎么没有想到的(嗯,我想到了,但它从我的脑海中溜走了)。我仍然需要将它们全部捕获到内存中(以便将它们保存到磁盘)并显示其中的一半 - 我会用计时器尝试一下,看看是否可以通过。
-
我认为每 4 帧显示一次就足够了 (30FPS),并且可能有助于 CPU 负载。你捕捉什么分辨率?硬件设备的接口是否“可拆分”一个连接到记录计算机第二个连接到用户界面计算机?
标签: c# wpf multithreading camera frame-rate