图像高斯滤波的Verilog实现
高斯滤波的原理:
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
高斯滤波函数:
高斯滤波被用作为平滑滤波器的本质原因是因为它是一个低通滤波器,而且大部份基于卷积平滑滤波器都是低通滤波器。本实验为3*3阶的计算算子:
根据该算子,可用Verilog来实现,难点主要是3*3矩阵的生成。前面的文章边缘检测已经实现了3*3矩阵的生成,原理都一样。
1 //************************************************************************** 2 // *** file name : Space_filter.v 3 // *** version : 1.0 4 // *** Description : 3*3 Weighted filtering 5 // *** Blogs : https://www.cnblogs.com/WenGalois123/ 6 // *** Author : Galois_V 7 // *** Date : 2022.10.16 8 // *** Changes : Initial 9 //************************************************************************** 10 `timescale 1ns/1ps 11 module Space_filter 12 ( 13 input i_sys_clk , 14 input i_sys_rstn , 15 input i_frame_rst , 16 input i_sf_en , 17 input i_sf_level , 18 input [9:0] i_s_tdata , 19 input i_s_tvalid , 20 output o_s_tready , 21 output [9:0] o_m_tdata , 22 output o_m_tvalid , 23 input i_m_tready 24 ); 25 26 wire w_rst_all ; 27 wire w_valid ; 28 wire [9:0] w_matrix_00 ; 29 wire [9:0] w_matrix_10 ; 30 wire [9:0] w_matrix_20 ; 31 wire [9:0] w_matrix_10t; 32 wire [9:0] w_matrix_20t; 33 wire [9:0] w_add_data ; 34 wire [9:0] w_add_2data ; 35 wire [11:0] w_add_4data ; 36 wire [12:0] w_add_20data; 37 wire [7:0] w_outslt ; 38 wire w_empty ; 39 wire w_prog_full ; 40 41 reg [1:0] r_sel_fun ; 42 reg r_1st_line_en; 43 reg r_2rd_line_en; 44 reg r_1st_left_en; 45 reg [7:0] r_matrix_01 ; 46 reg [7:0] r_matrix_02 ; 47 reg [7:0] r_matrix_11 ; 48 reg [7:0] r_matrix_12 ; 49 reg [7:0] r_matrix_21 ; 50 reg [7:0] r_matrix_22 ; 51 reg [9:0] r_data ; 52 reg [9:0] r_fifo_din ; 53 reg r_fifo_wr ; 54 55 56 assign w_rst_all = i_frame_rst & (~i_sys_rstn); 57 assign w_valid = o_s_tready & i_s_tvalid; 58 assign w_matrix_00 = i_s_tdata; 59 60 always@(posedge i_sys_clk) 61 begin 62 r_sel_fun <= {i_sf_en,i_sf_level}; 63 end 64 /******************************************************************************\ 65 Generate 3 * 3 matrix 66 \******************************************************************************/ 67 assign w_line0_rd = w_valid; 68 assign w_line1_rd = w_valid & r_1st_line_en; 69 assign w_line2_rd = w_valid & r_2rd_line_en; 70 71 always@(posedge i_sys_clk) 72 begin 73 if(w_rst_all) 74 begin 75 r_1st_line_en <= 'd0; 76 r_2rd_line_en <= 'd0; 77 r_1st_left_en <= 'd0; 78 end 79 else if(w_valid) 80 begin 81 if(w_matrix_00[8]) 82 begin 83 r_1st_line_en <= 1'b1; 84 r_2rd_line_en <= r_1st_line_en; 85 r_1st_left_en <= 1'b1; 86 end 87 else 88 begin 89 r_1st_left_en <= 1'b0; 90 end 91 end 92 end 93 94 fifo_2048x10 line1_fifo 95 ( 96 .clk (i_sys_clk ), 97 .srst (w_rst_all ), 98 .din (w_matrix_00 ), 99 .wr_en (w_line0_rd ), 100 .dout (w_matrix_10t ), 101 .rd_en (w_line1_rd ), 102 .full ( ), 103 .empty ( ) 104 ); 105 fifo_2048x10 line2_fifo 106 ( 107 .clk (i_sys_clk ), 108 .srst (w_rst_all ), 109 .din (w_matrix_10t ), 110 .wr_en (w_line1_rd ), 111 .dout (w_matrix_20t ), 112 .rd_en (w_line2_rd ), 113 .full ( ), 114 .empty ( ) 115 ); 116 117 assign w_matrix_10 = w_line1_rd ? w_matrix_10t : w_matrix_00; 118 assign w_matrix_20 = w_line2_rd ? w_matrix_20t : w_matrix_10; 119 120 always@(posedge i_sys_clk) 121 begin 122 if(w_valid) 123 begin 124 r_matrix_01 <= w_matrix_00[7:0]; 125 r_matrix_11 <= w_matrix_10[7:0]; 126 r_matrix_21 <= w_matrix_20[7:0]; 127 128 if(r_1st_left_en) 129 begin 130 r_matrix_02 <= w_matrix_00[7:0]; 131 r_matrix_12 <= w_matrix_10[7:0]; 132 r_matrix_22 <= w_matrix_20[7:0]; 133 end 134 else 135 begin 136 r_matrix_02 <= r_matrix_01; 137 r_matrix_12 <= r_matrix_11; 138 r_matrix_22 <= r_matrix_21; 139 end 140 end 141 end 142 143 /******************************************************************************\ 144 Data weighting processing 145 \******************************************************************************/ 146 assign w_add_data = w_matrix_00[7:0] + r_matrix_02 + w_matrix_20[7:0] + r_matrix_22; 147 assign w_add_2data = r_matrix_01 + w_matrix_10[7:0] + r_matrix_12 + r_matrix_21; 148 assign w_add_4data = {r_matrix_11,2'd0} + {w_add_2data,1'b0} + w_add_data; 149 assign w_add_20data = {r_matrix_11,4'd0} + w_add_4data; 150 151 assign w_outslt = r_sel_fun[0] ? w_add_4data[11:4] : w_add_20data[12:5]; 152 153 always@(*) 154 begin 155 case(r_sel_fun[1]) 156 1'b0 :begin r_data <= i_s_tdata;end 157 1'b1 :begin r_data <= (w_valid & r_1st_left_en) ? w_matrix_00 : {w_matrix_00[9:8],w_outslt}; end 158 default:r_data <= i_s_tdata; 159 endcase 160 end 161 162 always@(posedge i_sys_clk) 163 begin 164 if(w_rst_all) 165 begin 166 r_fifo_din <= 'd0; 167 r_fifo_wr <= 'd0; 168 end 169 else 170 begin 171 r_fifo_din <= r_data; 172 r_fifo_wr <= w_valid; 173 end 174 end 175 176 fifo_2048x10_f2000 dout_fifo 177 ( 178 .clk (i_sys_clk ), 179 .srst (w_rst_all ), 180 .din (r_fifo_din ), 181 .wr_en (r_fifo_wr ), 182 .dout (o_m_tdata ), 183 .rd_en (i_m_tready ), 184 .full ( ), 185 .empty (w_empty ), 186 .prog_full (w_prog_full ) 187 ); 188 189 assign o_m_tvalid = ~w_empty & i_m_tready; 190 assign o_s_tready = ~w_prog_full; 191 192 endmodule
具体实验就不做了,类似于上一个边缘检测的实验,只是对Y通道数据进行处理。3*3阶的高斯滤波效果并不是很明显,这里就不把实验的图展示了。