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/06 18:31:28
// Design Name:
// Module Name: ram_3x3_8bit
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module ram_3x3_8bit(clk, rst_n, per_clken,per_img,matrix_clken, matrix_p11, matrix_p12, matrix_p13, matrix_p21, matrix_p22, matrix_p23, matrix_p31, matrix_p32, matrix_p33 );input clk; input rst_n; input per_clken;//Prepared Image data output/capture enable clockinput [7:0] per_img;//Prepared Image brightness inputoutput matrix_clken;//Prepared Image data output/capture enable clock output reg [7:0] matrix_p11; output reg [7:0] matrix_p12; output reg [7:0] matrix_p13; //3X3 Matrix outputoutput reg [7:0] matrix_p21; output reg [7:0] matrix_p22; output reg [7:0] matrix_p23; output reg [7:0] matrix_p31; output reg [7:0] matrix_p32; output reg [7:0] matrix_p33;wire [7:0] row1_data;wire [7:0] row2_data;reg [7:0] row3_data;always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginrow3_data<=1'b0;endelse if(per_clken==1'b1)beginrow3_data<=per_img;endelse beginrow3_data<=row3_data;endendwire shift_clk_en = per_clken;c_shift_ram_0 uut1_Shift_RAM(.D(row3_data), // input wire [7 : 0] D.CLK(shift_clk_en), // input wire CLK.SCLR(~rst_n), // input wire SCLR.Q(row2_data) // output wire [7 : 0] Q);c_shift_ram_0 uut2_Shift_RAM(.D(row2_data), // input wire [7 : 0] D.CLK(shift_clk_en), // input wire CLK.SCLR(~rst_n), // input wire SCLR.Q(row1_data) // output wire [7 : 0] Q);//每个像素使能延时三个时钟周期 delay 3clk reg [1:0] per_clken_r;always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginper_clken_r<=1'b0;endelse beginper_clken_r <= {per_clken_r[0], per_clken}; endendwire read_clken = per_clken_r[0];assign matrix_clken = per_clken_r[1]; always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begin{matrix_p11, matrix_p12, matrix_p13} <= 1'b0;{matrix_p21, matrix_p22, matrix_p23} <= 1'b0;{matrix_p31, matrix_p32, matrix_p33} <= 1'b0;endelse if(read_clken==1'b1)begin{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data};{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data}; {matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data}; endelse begin{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p11, matrix_p12, matrix_p13};{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p21, matrix_p22, matrix_p23};{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p31, matrix_p32, matrix_p33};endendendmodule
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
