高斯滤波:高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。高斯滤波(Gauss filter)实质上是一种信号的滤波器,其用途为信号的平滑处理,数字图像用于后期应用,其噪声是最大的问题,因为误差会累计传递等原因,大多图像处理教材会在很早的时候介绍Gauss滤波器,用于得到信噪比SNR较高的图像(反应真实信号)。高斯平滑滤波器对于抑制服从正态分布的噪声非常有效。
下面介绍一种常用的简单高斯滤波处理
利用移位寄存器,taps0是最早存入的第一行数据,也就是y-1行,而taps1则是y行代表的数据,taps2是第三行的数据。根据公式进行流水线计算。代码中的matrix例化模块M_3_3是一个移位寄存器,可以输出3行最前端的数据,即每行的第一个数据(每行最先存入的那个数据)。
部分计算代码:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 15:53:28 2/13/2018
// Design Name:
// Module Name: gs_fil
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module gs_filter(
input clk ,
input rst_n ,
input [7:0] din ,
input din_vld ,
input din_sop ,
input din_eop ,
output reg [7:0] dout ,
output reg dout_vld ,
output reg dout_sop ,
output reg dout_eop
);
parameter DATA_WIDTH = 8 ;
parameter FIRST_MUX = 16 ;
reg [FIRST_MUX-1:0] gs_0 ;
reg [FIRST_MUX-1:0] gs_1 ;
reg [FIRST_MUX-1:0] gs_2 ;
wire [DATA_WIDTH-1:0] taps0 ;
wire [DATA_WIDTH-1:0] taps1 ;
wire [DATA_WIDTH-1:0] taps2 ;
reg [DATA_WIDTH-1:0] taps0_ff0;
reg [DATA_WIDTH-1:0] taps0_ff1;
reg [DATA_WIDTH-1:0] taps1_ff0;
reg [DATA_WIDTH-1:0] taps1_ff1;
reg [DATA_WIDTH-1:0] taps2_ff0;
reg [DATA_WIDTH-1:0] taps2_ff1;
reg din_vld_ff0;
reg din_vld_ff1;
reg din_vld_ff2;
reg din_sop_ff0;
reg din_sop_ff1;
reg din_sop_ff2;
reg din_eop_ff0;
reg din_eop_ff1;
reg din_eop_ff2;
//对应关系
// f(x-1,y-1), f(x,y-1), f(x+1,y-1) = Line2_ff[1] Line2_ff[0] Line2
// f(x-1,y+0), f(x,y+0), f(x+1,y+0) = Line1_ff[1] Line1_ff[0] Line1
// f(x-1,y+1), f(x,y+1), f(x+1,y+1) = Line0_ff[1] Line0_ff[0] Line0
//高斯滤波公式
// g(x,y)={f(x-1,y-1)+f(x-1,y+1)+f(x+1,y-1)+f(x+1,y+1)+[f(x-1,y)+f(x,y-1)+f(x+1,y)+f(x,y+1)]*2+f(x,y)*4}/16
// =(gs_0+gs_1+gs_2)/16
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
din_vld_ff0 <= 0;
din_vld_ff1 <= 0;
din_vld_ff2 <= 0;
din_sop_ff0 <= 0;
din_sop_ff1 <= 0;
din_sop_ff2 <= 0;
din_eop_ff0 <= 0;
din_eop_ff1 <= 0;
din_eop_ff2 <= 0;
end
else begin
din_vld_ff0 <= din_vld ;
din_vld_ff1 <= din_vld_ff0 ;
din_vld_ff2 <= din_vld_ff1 ;
din_sop_ff0 <= din_sop ;
din_sop_ff1 <= din_sop_ff0 ;
din_sop_ff2 <= din_sop_ff1 ;
din_eop_ff0 <= din_eop ;
din_eop_ff1 <= din_eop_ff0 ;
din_eop_ff2 <= din_eop_ff1 ;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
taps0_ff0 <= 0 ;
taps0_ff1 <= 0 ;
taps1_ff0 <= 0 ;
taps1_ff1 <= 0 ;
taps2_ff0 <= 0 ;
taps2_ff1 <= 0 ;
end
else if(din_vld_ff0)begin
taps0_ff0 <= taps0 ;
taps0_ff1 <= taps0_ff0 ;
taps1_ff0 <= taps1 ;
taps1_ff1 <= taps1_ff0 ;
taps2_ff0 <= taps2 ;
taps2_ff1 <= taps2_ff0 ;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
gs_0 <= 0 ;
end
else if(din_vld_ff1)begin
gs_0 <= (taps0_ff1 + taps1_ff1*2 + taps2_ff1);
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
gs_1 <= 0 ;
end
else if(din_vld_ff1)begin
gs_1 <= (taps0_ff0*2 + taps1_ff0*4 + taps2_ff0*2);
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
gs_2 <= 0 ;
end
else if(din_vld_ff1)begin
gs_2 <= (taps0 + taps1*2 + taps2);
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout <= 0;
end
else if(din_vld_ff2)begin
dout <= (gs_0 + gs_1 + gs_2) >> 4 ;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_sop <= 0;
end
else if(din_sop_ff2)begin
dout_sop <= 1'b1;
end
else begin
dout_sop <= 1'b0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_vld <= 0;
end
else if(din_vld_ff2)begin
dout_vld <= 1'b1;
end
else begin
dout_vld <= 1'b0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_eop <= 0;
end
else if(din_eop_ff2)begin
dout_eop <= 1'b1;
end
else begin
dout_eop <= 1'b0;
end
end
matrix M_3_3(
.clken(din_vld),
.clock(clk),
.shiftin(din),
//.shiftout(dout),
.taps0x(taps0),
.taps1x(taps1),
.taps2x(taps2)
);
endmodule