高斯濾波是很多圖像處理算法中最關鍵性的一個中間步驟,實現快速高斯濾波算法具有很重要的意義。
通過拜讀前輩們關於高斯濾波快速算法的相關文獻,實現了自己的快速高斯濾波算法,並用NEON指令加速了將近6倍。
1. 均值濾波逼近高斯濾波
這種算法優點是簡單。一般可以通過3次均值濾波就可以逼近高斯濾波的效果。當然,如果需要的精度更高,則需要更多次的均值濾波。簡單均值濾波需要根據高斯的delta參數確定均值濾波的長度,delta是連續的,而均值濾波的長度是整數,這樣造成對不同的delta的逼近有一定的誤差。均值濾波的O(1)時間復雜度的實現需要一個積分圖去做,需要占用一個和原始圖片相當的緩存。這樣均值濾波逼近高斯濾波需要計算3次積分圖,遍歷3次積分圖來計算均值。而且,這種算法沒法采用CPU的SIMD指令加速。
對均值濾波逼近高斯濾波及其精度改進的算法可以參考下面的文獻:
Peter Kovesi 2009, Arbitrary Gaussian Filtering with 25 Addtions and 5 Multiplications per Pixel
2. 擴展二項式濾波逼近高斯濾波
這一算法的參考文獻為:
extended binomial filter for Fast gaussian Blur
這種算法的思路仍然是用均值逼近,只是每次均值濾波的長度不同,而且是一種加權的均值。但是在實現的時候沒有用積分圖,而是遞歸計算均值。參考文獻里面提供了源代碼,其源代碼為photoshop的一種插件語言寫的。應該是我太愚鈍,沒有徹底領悟算法細節,它的代碼里面幾個重要的初始參數不知道如何確定。
根據我的經驗,上述算法在實際中並不比遞歸濾波實現的要快,因為它的代碼里面在做豎直方向上遞歸計算均值濾波的時候是跨行訪問圖像數據的。這種算法也沒法用CPU的SIMD指令加速。
3. IIR濾波逼近高斯濾波
這種算法的參考文獻主要有:
Rachid Deriche - "Recursively implementing the Gaussian and its derivatives", 1993.
Lucas J. van Vliet, Ian T. Young and Piet W. Verbeek - "Recursive Gaussian derivative Filters", 1998
Dave Hale, "Recursive Gaussian Filters", CWP-546
這種算法是實現是級聯了兩個IIR濾波器,其中一個是非因果的IIR濾波過程。
另外,intel網站有一篇關於用SSE指令優化之后的IIR遞歸逼近高斯濾波的代碼,不過代碼寫的太龐雜了,非專業人士可及也!
關於IIR濾波實現高斯濾波有很多的編程技巧,尤其是在用NEON指令加速遞歸IIR濾波的時候,具體細節不便闡述。
4. IIR遞歸高斯濾波的性能測試
4.1 與Photoshop cs5.0版本的對比
時間 | 處理器 | |
Photoshop CS5.0高斯濾鏡 半徑250 700W像素彩色照片 | 1.5秒 | intel I3 CPU主頻2.3Ghz 2G內存 |
My 高斯濾鏡 半徑250 700W像素彩色照片 | 1秒 | intel I3 CPU主頻2.3Ghz 2G內存 |
注:PS cs5的高斯對不同半徑的高斯濾波做了不同的優化,它在半徑很小的時候極快,不排除其做了多核優化,而IIR遞歸濾波算法對所以的半徑計算時間完全一樣。
4.2 在RVDS環境下的性能測試數據
指令數 | 周期數 | 處理器 | |
C 代碼,1024x768 灰度圖像 | 110M | 194M | ARM-cortex A8 |
NEON指令匯編代碼,1024x768 灰度圖像 | 34M | 35M | ARM-cortex A8 |
C 代碼,1024x768 彩色圖像 | 338M | 558M | ARM-cortex A8 |
NEON指令匯編代碼,1024x768 彩色圖像 | 84M | 85M | ARM-cortex A8 |
4.3 在IPod真實設備上的測試數據
時間 | 設備 | |
NEON指令匯編代碼,720x576 灰度圖像 | 25ms | IPod4 |
4.4 內存消耗
內存RAM消耗 | |
C代碼 | 2 * MAX(width,height) |
NEON指令匯編代碼 | 8 * MAX(width,height) |