基於FPGA的均值濾波算法的實現
前面實現了基於FPGA的彩色圖像轉灰度處理,減小了圖像的體積,但是其中還是存在許多噪聲,會影響圖像的邊緣檢測,所以這一篇就要消除這些噪聲,基於灰度圖像進行圖像的濾波處理,為圖像的邊緣檢測做好夯實基礎。
椒鹽噪聲(salt & pepper noise)是數字圖像的一個常見噪聲,所謂椒鹽,椒就是黑,鹽就是白,椒鹽噪聲就是在圖像上隨機出現黑色白色的像素。椒鹽噪聲是一種因為信號脈沖強度引起的噪聲,產生該噪聲的算法也比較簡單。
均值濾波的方法將數據存儲成3x3的矩陣,然後求這個矩陣。在圖像上對目標像素給一個模板,該模板包括了其周圍的臨近像素(以目標象素為中心的周圍 8 個像素,構成一個濾波模板,即去掉目標像素本身),再用模板中的全體像素的平均值來代替原來像素值。
如圖所示,我們要進行均值濾波首先要生成一個3x3矩陣。算法運算窗口一般采用奇數點的鄰域來計算中值,最常用的窗口有3X3和5X5模型。下面介紹3X3窗口的Verilog實現方法。
(1)通過2個或者3個RAM的存儲來實現3X3像素窗口;
(2)通過2個或者3個FIFO的存儲來實現3X3像素窗口;
(3)通過2行或者3行Shift_RAM的存儲來實現3X3像素窗口;
要想用實現均值濾波和中值濾波,必須要先生成3x3陣列,在Altera系列裏,可以用QuatusII調用IP核——shift_RAM,具體設置參數如圖所示。
如上圖所示,其中shiftin是實時輸入的數據,taps1x,taps2x輸入數據的第二三行,當數據輸入成一行三個時,自動跳到下一行,最終形成每行是三列的一個矩陣,用均值濾波和中值濾波的處理方法即可,這樣基本是每一個目標都可以找到自己對應的一個3x3矩陣,最後進行處理。先進入IP核裏面的是最開始的的數據,所以在讀出的時候也是要放在第一行。
關於shift_ram的更詳細的解釋可以查看我的另一篇博文:http://www.cnblogs.com/ninghechuan/p/6789399.html。
這學期做比賽用的是國產FPGA,開發軟件是PDS,這個軟件說實話比較簡潔,快,裏面也有shift_ram IP core,但是不能設置多行(一個IP只能存儲一行),不過只要你理解了shift_ram的工作的原理,完全可以用幾個來實現多行處理,我通過PDS開發套件調用兩個shift_register IP核來生成3X3矩陣實現3X3像素窗口。shift_register IP核可定義數據寬度、移位的行數、每行的深度。這裏我們需要8bit。640個數據每行,同事移位寄存2行即可。同時選擇時鐘使能端口clken。
1 shift_ram_end u_shift_ram_end1 2 ( 3 .din (row3_data), 4 .clk (shift_clk_en), 5 .rst (~rst_n), 6 .dout (row2_data) 7 ); 8 9 shift_ram_end u_shift_ram_end2 10 ( 11 .din (row2_data), 12 .clk (shift_clk_en), 13 .rst (~rst_n), 14 .dout (row1_data) 15 );
如圖所示,我們這裏將行設置為8,場設置為4,所以可以明顯的看到,當數據緩存到一行時,就會移位寄存到下一行,緩存兩行後便會生成3X3矩陣。
如圖所示,比較緩存的第一行的數據在3x3矩陣中,占第一行,結果相同,顯然是正確的。
如圖所示,第二行、第三行和最終生成的3x3矩陣作比較,結果顯然是正確的。
1 //wire [32:0] matrix_row1 = {matrix_p11, matrix_p12,matrix_p13};//just for test 2 //wire [32:0] matrix_row2 = {matrix_p21, matrix_p22,matrix_p23}; 3 //wire [32:0] matrix_row3 = {matrix_p31, matrix_p32,matrix_p33}; 4 always @(posedge clk or negedge rst_n) 5 begin 6 if(!rst_n)begin 7 {matrix_p11, matrix_p12, matrix_p13} <= 33‘h0; 8 {matrix_p21, matrix_p22, matrix_p23} <= 33‘h0; 9 {matrix_p31, matrix_p32, matrix_p33} <= 33‘h0; 10 end 11 else if(read_frame_href)begin 12 if(read_frame_clken)begin//shift_RAM data read clock enbale 13 {matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data};//1th shift input 14 {matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data};//2th shift input 15 {matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data};//3th shift input 16 end 17 else begin 18 {matrix_p11, matrix_p12, matrix_p13} <= {matrix_p11, matrix_p12, matrix_p13}; 19 {matrix_p21, matrix_p22, matrix_p23} <= {matrix_p21, matrix_p22, matrix_p23}; 20 {matrix_p31, matrix_p32, matrix_p33} <= {matrix_p31, matrix_p32, matrix_p33}; 21 end 22 end 23 else begin 24 {matrix_p11, matrix_p12, matrix_p13} <= 33‘h0; 25 {matrix_p21, matrix_p22, matrix_p23} <= 33‘h0; 26 {matrix_p31, matrix_p32, matrix_p33} <= 33‘h0; 27 end 28 end3x3矩陣生成
1 assign post_img_Y = mean_value4[10:3];//求平均值除以8,向右移位3位
如圖所示,將3x3矩陣的中心像素的周圍八個點求和,我們上面還是采取了流水線的設計方法,來增加吞吐量,然後再求平均值代替目標像素的值,從波形圖上觀察,計算的結果顯然是正確的。這樣便完成了均值濾波的仿真。
1 //-------------------------------------------- 2 //Generate 8bit 3x3 matrix for video image processor 3 //Image data has been processd 4 wire matrix_frame_vsync; //Prepared Image data vsync valid signal 5 wire matrix_frame_href; //Prepared Image data href vaild signal 6 wire matrix_frame_clken; //Prepared Image data output/capture enable clock 7 wire [7:0] matrix_p11, matrix_p12, matrix_p13;//3x3 materix output 8 wire [7:0] matrix_p21, matrix_p22, matrix_p23; 9 wire [7:0] matrix_p31, matrix_p32, matrix_p33; 10 11 shift_RAM_3x3 u_shift_RAM_3x3 12 ( 13 //global signals 14 .clk (clk), 15 .rst_n (rst_n), 16 //Image data prepred to be processd 17 .per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal 18 .per_frame_href (per_frame_href), //Prepared Image data href vaild signal 19 .per_frame_clken (per_frame_clken), //Prepared Image data output/capture enable clock 20 .per_img_Y (per_img_Y), //Prepared Image brightness input 21 22 //Image data has been processd 23 .matrix_frame_vsync (matrix_frame_vsync), //Prepared Image data vsync valid signal 24 .matrix_frame_href (matrix_frame_href), //Prepared Image data href vaild signal 25 .matrix_frame_clken (matrix_frame_clken), //Prepared Image data output/capture enable clock 26 .matrix_p11 (matrix_p11), 27 .matrix_p12 (matrix_p12), 28 .matrix_p13 (matrix_p13), //3X3 Matrix output 29 .matrix_p21 (matrix_p21), 30 .matrix_p22 (matrix_p22), 31 .matrix_p23 (matrix_p23), 32 .matrix_p31 (matrix_p31), 33 .matrix_p32 (matrix_p32), 34 .matrix_p33 (matrix_p33) 35 36 ); 37 38 //----------------------------------------------------------------------- 39 //step1 40 reg [10:0] mean_value1, mean_value2, mean_value3; 41 always @(posedge clk or negedge rst_n) 42 begin 43 if(!rst_n)begin 44 mean_value1 <= 11‘d0; 45 mean_value2 <= 11‘d0; 46 mean_value3 <= 11‘d0; 47 end 48 else begin 49 mean_value1 <= matrix_p11 + matrix_p12 + matrix_p13; 50 mean_value2 <= matrix_p21 + 11‘d0 + matrix_p23; 51 mean_value3 <= matrix_p31 + matrix_p32 + matrix_p33; 52 end 53 end 54 55 //step2 56 reg [10:0] mean_value4; 57 always @(posedge clk or negedge rst_n) 58 begin 59 if(!rst_n) 60 mean_value4 <= 11‘d0; 61 else 62 mean_value4 <= mean_value1 + mean_value2 + mean_value3; 63 end對3x3矩陣求均值
當然,最後為了保持時鐘的同步性,將消耗的時鐘延時輸出。
1 //------------------------------------------------------------ 2 //delay 2 clk 3 reg [1:0] per_frame_clken_r; 4 reg [1:0] per_frame_href_r; 5 reg [1:0] per_frame_vsync_r; 6 7 always @(posedge clk or negedge rst_n) 8 begin 9 if(!rst_n)begin 10 per_frame_clken_r <= 2‘b0; 11 per_frame_href_r <= 2‘b0; 12 per_frame_vsync_r <= 2‘b0; 13 end 14 else begin 15 per_frame_clken_r <= {per_frame_clken_r[0], matrix_frame_clken}; 16 per_frame_href_r <= {per_frame_href_r[0], matrix_frame_href}; 17 per_frame_vsync_r <= {per_frame_vsync_r[0], matrix_frame_vsync}; 18 end 19 end 20 21 assign post_frame_vsync = per_frame_vsync_r[1]; 22 assign post_frame_href = per_frame_href_r[1]; 23 assign post_frame_clken = per_frame_clken_r[1];保持時鐘的同步性
圖上為灰度圖像,圖下為均值濾波後的圖像,可以看出濾波後的圖像有一些模糊,這是因為均值濾波就是將圖像做平滑處理,像素值高的像素會被拉低,像素值低像素會被拉高,趨向於一個平均值,所以圖像會變模糊一些。這樣基於FPGA的均值濾波就完成了,下一篇我會發布基於FPGA的中值濾波處理,並且比較這兩種濾波方式的優劣,最終選取較好的一種濾波方式進行圖像邊緣檢測處理。
轉載請註明出處:NingHeChuan(寧河川)
個人微信訂閱號:NingHeChuan
如果你想及時收到個人撰寫的博文推送,可以掃描左邊二維碼(或者長按識別二維碼)關註個人微信訂閱號
知乎ID:NingHeChuan
微博ID:NingHeChuan
原文地址:http://www.cnblogs.com/ninghechuan/p/6984705.html
基於FPGA的均值濾波算法的實現