高斯滤波的FPGA实现

高斯滤波:高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。高斯滤波(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

猜你喜欢

转载自blog.csdn.net/emperor_strange/article/details/87918911