簡體   English   中英

以高幀頻顯示圖像

[英]Displaying images with a high frame rate

問題出在這里:我有一個自定義的硬件設備,我必須在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 /內核數不超過一個,那當然會完全殺死機器,這是不可接受的。 另外,我通過這種方式存在大量線程爭用。

問題很明顯-是否有更好的選擇,或者在這種情況下是其中一種選擇?

更新:
我以某種方式忘了提及(嗯,在寫這個問題時忘了思考),但是我當然不需要顯示所有框架,但是我仍然需要捕獲所有框架,以便將它們保存到硬盤。

Update2:我發現DispatcherTimer方法很慢,不是因為它不能足夠快地處理所有事情,而是因為DispatcherTimer在觸發滴答聲事件之前等待下一個垂直同步。 對於我而言,這實際上是很好的,因為在滴答事件中,我可以將所有待處理的圖像保存到內存緩沖區(用於將圖像保存到磁盤)並僅顯示最后一個。

至於被捕獲完全“殺死”的舊計算機,看來WPF會退回到非常慢的軟件渲染中。 我可能無能為力。

感謝所有的答案。

我認為您嘗試的是過於簡單的方法。 這就是我要做的。

a)將Thread.Sleep(5)放入輪詢循環中,這應該使您可以接近120fps,同時仍保持較低的CPU時間。

b)僅每5幀左右更新一次顯示。 因為我不確定WPF是否可以處理超過60fps的幀,這將減少處理量。

c)使用ThreadPool為每個幀生成一個子任務,然后將其保存到磁盤(每幀單獨的文件)中,這樣您就不會受到磁盤性能的限制。 多余的幀只會堆積在內存中。

我個人將按此順序實施它們。 a或b可能會解決您的問題。

您可以執行以下操作(所有psuedocode):1.運行一個工作線程來處理捕獲過程:

List<Image> _captures = new List<Image>();
 new Thread(() =>
    {
        while (StillCapturing)
        {
            if (Camera.CheckForAndDownloadImage(CameraInstance))
            {
                lock(_locker){_captures.Add(DisplayImage);


            }
        }
    }).Start();
  1. 讓調度程序計時器線程獲取最新捕獲的圖像(很明顯,自上次滴答之后它會丟失一些捕獲)並顯示。 因此,UI線程受到限制,並盡可能少地做,它並沒有完成所有的“捕獲”,這是由工作線程完成的。 抱歉,我無法格式化(但是您明白了):

     void OnTimerTick(can't remember params) 

    {Image imageToDisplay; lock(_locker){imageToDisplay = _captures [k.Count-1]; DisplayFunction(imageToDisplay); }

  2. 可能是該列表是一個隊列,而另一個線程用於排空該隊列並寫入磁盤等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM