FPGA-均值滤波算法的实现

1.  背景知识

       均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括
了其周围的临近像素(以目标像素为中心的周围 8 个像素,构成一个滤波模板,即去掉目
标像素本身),再用模板中的全体像素的平均值来代替原来像素值。
均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用
均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模
板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),
作为处理后图像在该点上的灰度 g(x,y),即 g(x,y)=1/m ∑f(x,y) m 为该模板
中包含当前像素在内的像素总个数。
均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也
破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。


2. FPGA  的均值滤波算法实现步骤

(x-1,y-1)  (x,y-1)  (x+1,y-1)
(x-1,y)       (x,y)      (x+1,y)
(x-1,y+1) (x,y+1) (x+1,y+1)

3x3 像素坐标位置
中心点(x,y)为均值滤波将要处理的位置,
f(x,y)表示(x,y)点的像素值,
g(x,y)表示(x,y)点经过均值处理后的值。
均值滤波公式表示如下:
g(x,y)=1/8*(f(x-1,y-1)+f(x,y-1)+f(x+1,y-1)
+f(x-1,y)+f(x+1,y)+
f(x-1,y+1)+f(x,y+1)+f(x+1,y+1))------------------------------(1)
由(1)式我们看出(x,y)点的 3x3 像素点的均值等于其周围邻域的八个点的像素值之和
除以 8。
FPGA 实现步骤:
1>形成 3x3 矩阵像素
2>求周围邻域八个点的像素值之和
3>将结果右移三位(相当于除以 8)得到结果。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/05/08 20:27:48
// Design Name: 
// Module Name: Mean_filter
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module Mean_filter(
	clk,
	rst_n,
	img_i,
	clken_i,
	img_o,
	clken_o,
	ram_addr
    );
	input clk;
	input rst_n;
	input [7:0]img_i;
	input clken_i;
	
	output [7:0]img_o;
	output clken_o;
	output reg [15:0]ram_addr;
	
	//产生3x3阵列
	wire 	[7:0] 	matrix_p11, matrix_p12, matrix_p13;//3x3 
	wire 	[7:0]	matrix_p21, matrix_p22, matrix_p23;
	wire 	[7:0]	matrix_p31, matrix_p32, matrix_p33;
	wire 			matrix_clken;
	ram_3x3_8bit uut_ram_3x3_8bit(
	.clk(clk),						
	.rst_n(rst_n),							
	
	.per_clken(clken_i),
	.per_img(img_i),
	
	.matrix_clken(matrix_clken),	
	.matrix_p11(matrix_p11),						
	.matrix_p12(matrix_p12),						
	.matrix_p13(matrix_p13),	
	.matrix_p21(matrix_p21),						
	.matrix_p22(matrix_p22),						
	.matrix_p23(matrix_p23),						
	.matrix_p31(matrix_p31),						
	.matrix_p32(matrix_p32),						
	.matrix_p33(matrix_p33)
    );
	//这里流水处理首先把每个行的相加 -1
	reg [10:0] mean_val_1,mean_val_2, mean_val_3;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			mean_val_1<=0; 
			mean_val_2<=0; 
			mean_val_3<=0; 
		end
		else begin
			mean_val_1<= matrix_p11 + matrix_p12 + matrix_p13;
			mean_val_2<= matrix_p21 + 11'd0      + matrix_p23;
			mean_val_3<= matrix_p31 + matrix_p32 + matrix_p33;
		end
	end
	//然后相加   -2
	reg [10:0] sum_mean;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			sum_mean<=1'b0;
		end
		else begin
			sum_mean<= mean_val_1 + mean_val_2 + mean_val_3;
		end
	end 
	//二级流水线打拍 打2拍
	reg 	[1:0]	per_clken_r;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			per_clken_r <= 2'b0;
		end
		else begin
			per_clken_r <= {per_clken_r[0], matrix_clken};
		end
	end
	
	assign	clken_o 	= 	per_clken_r[1];
	
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			ram_addr<=1'b0;
		end
		else if(clken_o== 1'b1)begin
				ram_addr<=ram_addr+1'b1;
		end
		else begin
			ram_addr<=ram_addr;
		end
	end
	
	assign img_o =sum_mean[10:3];
	
endmodule

猜你喜欢

转载自blog.csdn.net/weixin_41445387/article/details/90139890