以前有篇文章,講《讓你的軟件飛起來》,講的是怎麼用C語言實現RGB轉YUV的方法,從浮點乘法到定點乘法,最後再到查找表等方法進行加速,整體提升了幾百倍的提升。
那麼FPGA進行圖像加速也有異曲同工之筆。由于FPGA的數字電路結構,沒有CPU線程的概念,更沒有浮點的概念,那麼直觀的想,我想可以通過以下幾個方面進行運算的加速:
1)面積換速度:也就是串轉并運算,可以多個模塊同時計算;
2)時間換空間:時序收斂下通過頻率提高性能,雖然面積可能稍微加大點;
3)流水線操作:讓整個“生産線”全速運行,等同于n倍線程效率;
4)乒乓操作:等同關于2個模塊的并行運算,讀寫互不沖突;
5)浮點轉定點:采用乘法 移位的方式轉換;
6)查找表換計算:采用查找表替代某些有限固定值的運算;
7)等等各種别的技巧。
整體的思路和《讓你的軟件飛起來》有點相似,那就是不要用浮點,能用查找表的不要計算,能并行(多線程)的不要單線程,當然Pipeline CPU做不到。我們在使用FPGA進行加速時候,講的是硬件加速,那麼要充分發揮硬件的性能,就需要充分使用這些技巧,于是乎用FPGA實現并不是最難的,最難得是如何設計FPGA硬件架構(實現隻是個翻譯而已)。有一本我也沒啃破的書《Computer Architecture》,如果你能沉得下心,建議去看看英文版。
所謂硬件架構,就是如何用最優的方式去實現,在理論基礎和經驗的前提下,結合FPGA本身的固有特性,設計出基于FPGA的實現方案,這本身思維非常重要,因為是和硬件強相關的。拿Sobel邊緣檢測來說事,首先羅列一下工作量,我們需要完成如下功能:
1)CMOS攝像頭的驅動與數據的采集(灰度相機直接跳(4))
2)可選的Bayer轉RGB(ISP領域叫做Demosaic,但這個内容太多此處不展開,本教程制作簡單的Bayer轉RGB)
3)可選的RGB轉YUV并提取灰度圖像流
4)進行必要的中值濾波進行噪聲的去除以提升質量
5)進行3*3 Sobel邊緣檢測算法,同時計算H與V方向的梯度,得到結果
6)進行必要的腐蝕/膨脹運算
7)SDR/DDR外部存儲介質的圖像的乒乓緩存
8)HDMI/VGA接口顯示器的實時顯示驅動
9)必要的一些控制單元,包括複位、Sobel阈值、LED指示燈等等
完成以上功能,如果采用CPU實現,需要進行多次内存讀寫進行每一個模塊的計算,并且每一個模塊也隻能按從前到後點順序進行,不能Pipeline運算,這使得内存和計算非常耗時。簡單的畫了一下實現的框圖,如下所示,感覺徘徊的好累好心塞。
但如果采用FPGA實現,就不一樣了,首先前面模塊計算完幾行的值,後面的模塊就可以緊接着進行計算,那麼流水線可以High起來;其次前面講到的浮點轉定點,乒乓操作,面積換速度等等思維可以全部用上;最後數據隻進一次内存,讀寫乒乓後就顯示器實時顯示。采用FPGA實現的框圖,分别如下所示:
需要注意的是,要實時顯示就得緩存,因為攝像頭的時序并不一定或者一般都一定不會和顯示器匹配,這就是我們所謂的“顯卡”。我曾經用FPGA做了一個顯卡,讓小朋友們可以用51單片機驅動VGA顯示。
使用FPGA就是要充分利用電路的優勢,在資源足夠的情況下盡可能的流水線或者并行運算,最後達到實時處理的效果。曾經有一個哥們說他用DSP做了640*480 3次濾波就卡的隻有15FPS了(估計沒優化),但讓我用FPGA完成上面所有的圖像處理,做到300FPS也是輕而易舉的事情,這就是FPGA的優勢。至于具體的實現,在上圖框架定下來的前提下,剩下的就是具體的實現以及翻譯工作了。本教程全文都是在講解如何實現每一個模塊,以及最終流水線完成實時圖像處理的功能。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!