基于FPGA的中值滤波器设计
文章目錄
- 簡介
- 統計排序濾波
- 基于FPGA的統計排序濾波器
- 并行全比較排序法
- 整體設計與模塊劃分
- median_1d 模塊設計
- median_2d模塊設計
- 仿真與調試
- 福利
簡介
學習本教程需要一定的基礎,主要參考<<基于FPGA的數字圖像處理原理及應用>>的第八章,建議大家可以先看看書上的內容,尤其是一些理論推導,這里我就不詳細展開了。為了簡化開發難度,這里規定圖像格式為6404808bit @60的灰度圖,也就是圖像分辨率為640*480,一個像素占8個bit,幀率為60。
統計排序濾波
設r為處理窗口半徑,I(x,y)為輸入像素值,g(x,y)為輸出像素值,則有如下定義:
g(x,y)=Sort(I(x+i,y+i),n) ,-r≤i≤r,-r≤j≤r,0≤n<(2r+1)^2.
令n=(2r+1)2/2,則上式變為中值濾波器。常用的排序算子有冒泡排序、希爾排序即簡單排序等,以冒泡排序為例,C++語言處理算法如下:
中值濾波能夠很好的消除椒鹽噪聲。效果圖如下所示:
基于FPGA的統計排序濾波器
并行全比較排序法
為了區別相同的數值,對各個數值的輸入次序做如下規定:
- 當前數值大于本數據之前輸入數據時,結果記為1,小于或等于時記為0.
- 當前數值大于或等于本數據之后輸入數據時,結果記為1,小于時記為0.
- 與自身比較記為0.
利用此規則對輸入數據進行排序,如下表所示:
以3個數據d1,d2,d3的排序為例,需要設計的比較器數目為n(n-1)個。如下所示:
整體設計與模塊劃分
采用與均值濾波類似的方法,先進行一維圖像行方向上的排序,再對列方向上的行排序結果進行排序,即可得到一個窗口方向上的排序。同樣的,行方向的對齊采用行緩存來實現,如下圖所示:
注意:并行全比較排序與C語言實現的冒泡排序結果,在某些特殊情況下還是有點差別的。如下所示:
(1) 如果使用C語言冒泡排序,目標值會被判定為1,因為這9個數的排序如下:
1, 1, 1, 1 ,1, 0, 0, 0, 0
其中值為1,故判定為1.
(2) 使用先行后列的全排序法,每行的中值如下:
再對這3個數進行排序,得到最終的中值為0.與C語言冒泡排序判定結果不同。只有在1與0的比值為5:4或4:5的情況下才會出現,其他比值則不會出現判定結果不同。即便某些情況下判定結果可能不同,但他們都是中值附近的值,都具有中值濾波的效果。自己可以多列幾種情況試試看。
想強調的是,先行后列的并行全比較排序和C語言的冒泡排序數據結果對比時,可能會出現某些數據不同,免得大家懷疑是程序編寫錯誤。
median_1d 模塊設計
全并行排序的計算步驟如下;
(1) 首先得到待排序的n個數據:可以通過打n-1拍得到。
(2) 進行全比較:當前數據與其他所有數據依次比較,并記錄比較結果。
(3) 將(2)中的記錄結果相加.
(4) 查找(3)中相加結果按指定次序輸出。
一維排序濾波電路設計如下所示:
需要注意的是:din_r[2]為輸入第0個數據,din_r[1]為輸入第1個數據,din_r[0]為輸入第2個數據。
由于在求cmp_sum時,消耗了一個時鐘周期,所以在求dout時,需要先對輸入數據打一拍,即此時din_r[3]為輸入第0個數據,din_r[2]為輸入第1個數據,din_r[1]為輸入第2個數據。
- 當cmp_sum[0]==OUT_ID時,將第0個數據(din_r[3])賦值給dout,
- 當cmp_sum[1]==OUT_ID時,將第1個數據(din_r[2])賦值給dout,
- 當cmp_sum[2]==OUT_ID時,將第2個數據(din_r[1])賦值給dout。
從上圖可以看出,產生dout共需消耗5個時鐘周期,dout_vld需要和dout信號同步,故同樣需要對dout_vld打5拍,如下所示:
上圖中的KSZ為窗口長度,KSZ的值為3,故一行數據有兩個數據無法做中值處理,所以dout_vld信號產生代碼如下:
median_2d模塊設計
采用和均值濾波同樣的思路來處理,整個計算步驟如下:
(1) 計算一維行方向的排序結果輸出。
(2) 將第(1)步的結果接入第一個行緩存,第一個行緩存的輸出接入第二個行緩存,得到3行的一維輸出。
(3) 對第(2)步輸出的三個數據進行排序,得到結果輸出。
(4) 完成時序對齊。
二維運算的電路設計如下圖所示:
由于行FIFO讀出數據有一拍延時,所以median_1d輸出的數據需要延時一拍,以便于FIFO讀出數據對齊。從圖4-6可以看出,產生median_data共需消耗3個時鐘周期,median_vld有line_rd_en[2]產生,也需要延時3個時鐘周期,以便于median_data信號對齊,產生代碼如下:
由于median_vld由line_rd_en[1]產生,故已經舍去了兩行,所以此時不需要再與上其他信號了,注意與median_1d模塊的dout_vld做對比,自己理解一下。
仿真與調試
median_1d的測試激勵如下:
測試激勵主要是產生0-9共10個數據,仿真結果如下所示:
可以看出,中值結果是正確,尤其需要注意的是紅色框框里的數據,8和1共產生了2次,這個地方使用書上的代碼是有問題的。具體的自己看代碼就知道了。
median_2d仿真有點麻煩,自己可以使用mspaint畫圖軟件產生10*10的黑白圖,然后再用qt將其轉成txt,最后再使用modelsim進行仿真。也可以自己寫測試激勵。最終中值濾波結果如下圖所示:
福利
本教程的所有verilog源碼以及上位機源碼都會公布,微信掃描下面的二維碼關注[春哥筆記]公眾號,回復“非線性濾波”即可Get源碼的獲取方式。
總結
以上是生活随笔為你收集整理的基于FPGA的中值滤波器设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式笔记(2)工厂方法模式
- 下一篇: gui显示文本动态框