FPGA图像处理之均值滤波

编程入门 行业动态 更新时间:2024-10-27 23:28:17

FPGA<a href=https://www.elefans.com/category/jswz/34/1769353.html style=图像处理之均值滤波"/>

FPGA图像处理之均值滤波

1.均值滤波算法的理论

所有的滤波算法都是通过当前像素周边的像素,以一定的权重加权计算滤波后的结果。因此主要涉及两个变量:窗口内像素的权重值,以及窗口的大小。滤波的窗口有3x3、5x5、7x7、11x11等,窗口的尺度越大,相应的计算量越大,效果也越明显。
均值滤波可以简单的表示为在邻域窗3x3内,所有的像素权重相同,简单加权后求平均值,因此,图像中的噪声并没有被去除,只是被平均了而已。此外,均值滤波除了抑制噪声,也有平滑纹理的效果。如果窗口很大,也会产生模糊的效果。

2.均值滤波的FPGA实现

通过在图像上进行滑窗处理,可以获得以目标像素为中心的3x3窗口,从图像左上角开始,每次计算完当前像素后,再往右滑动一个像素,以新的窗口计算新的像素;当窗口滑动到行内最后一个像素并完成计算后,另起一行重新开始滑窗运算操作。
为了生成以目标像素为中心的3x3窗口,需要缓存3行像素,但在设计时只需要缓存两行像素,第三行像素实时输入即可。以FIFO方式对行像素进行缓存,并以菊花链的形式连接行缓存,即将当前行缓存的输出接到下一个行缓存的输入。

矩阵代码:

module Matrix_Generate_3x3_8Bit
#(parameter [10:0] IMG_HDISP = 11'd640;parameter [10:0] IMG_VDISP = 11'd480;parameter [10:0] DELAY_NUM = 11'd10
)
(input            clk,input            rst_n,input            per_img_vsync,input            per_img_href,input [7:0]      per_img_gray,output           matrix_img_vsync,output           matrix_img_href,output           matrix_top_edge_flag,output           matrix_bottom_edge_flag,output           matrix_left_edge_flag,output           matrix_right_edge_flag,output reg [7:0] matrix_p11;output reg [7:0] matrix_p12;output reg [7:0] matrix_p13;output 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;
);reg [10:0] hcnt;always@(posedge clk or rst_n)beginif(!rst_n)hcnt <= 11'b0;else beginif(per_img_href == 1'b1)hcnt <= hcnt + 1'b1;else hcnt <= 11'b0;endendreg   per_img_href_dly;always@(posedge clk or negedge rst_n)beginif(!rst_n)per_img_href_dly <= 1'b0;elseper_img_href_dly <= per_img_href;endwire img_href_neg = ~per_img_href & per_img_href_dly;reg [10:0] vcnt;always@(posedge clk or negedge rst_n)beginif(!rst_n)vcnt <= 11'b0;else beginif(per_img_vsync == 1'b0)vcnt <= 11'b0;else if(img_href_neg == 1'b1)vcnt <= vcnt + 1'b1;else vcnt <= vcnt;endendreg [10:0] extend_last_row_cnt;always@(posedge clk or negedge rst_n)beginif(!rst_n)extend_last_row_cnt <= 11'b0;else beginif((per_img_href == 1'b1)&&(vcnt == IMG_VDISP - 1'b1)&&(hcnt==IMG_HDISP - 1'b1)extend_last_row_cnt <= extend_last_row_cnt +1'b1;elseextend_last_row_cnt <= 11'b0;endendwire extend_last_row_en = (extend_last_row_cnt > DELAY_NUM)wire       fifol_wenb;wire [7:0] fifol_wdata;wire       fifol_renb;wire [7:0] fifol_rdata;wire       fifo2_wdata;wire [7:0] fifo2_wdata;wire       fifo2_renb;wire [7:0] fifo2_rdata;assign fifol_wenb = per_img_href;assign fifol_wdata = per_img_gray;assign fifo1_renb = per_img_href & (vcnt > 11'b0) | extend_last_row_en;assign fifo2_wenb = per_img_href & (vcnt > 11'b0);assign fifo2_wdata = fifo1_rdata;assign fifo2_renb  = per_img_href & (vcnt > 11'b1) | extend_last_row_en;sync_fifo
#(.C_FIFO_WIDTH   (8      ),.C_FIFO_DEPTH   (1024   )
)
u1_sync_fifo
(.rst        (~rst_n     ),.clk        (clk        ),.wr_en      (fifo1_wenb ),.din        (fifo1_wdata), .full       (           ),.rd_en      (fifo1_renb ),.dout       (fifo1_rdata),.empty      (           ),.data_count (           )
);sync_fifo
#(.C_FIFO_WIDTH   (8      ),.C_FIFO_DEPTH   (1024   )
)
u2_sync_fifo
(.rst        (~rst_n     ),.clk        (clk        ),.wr_en      (fifo2_wenb ),.din        (fifo2_wdata), .full       (           ),.rd_en      (fifo2_renb ),.dout       (fifo2_rdata),.empty      (           ),.data_count (           )
);
//  Read data from fifo
always @(posedge clk or negedge rst_n)
beginif(!rst_n)begin{matrix_p11, matrix_p12, matrix_p13} <= 24'h0;{matrix_p21, matrix_p22, matrix_p23} <= 24'h0;{matrix_p31, matrix_p32, matrix_p33} <= 24'h0;endelsebegin{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, fifo2_rdata};      //  1st row input{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, fifo1_rdata};      //  2nd row input{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, per_img_gray};     //  3rd row inputend
endreg             [1:0]           vsync;
reg             [1:0]           href;
reg             [1:0]           top_edge_flag;
reg             [1:0]           bottom_edge_flag;
reg             [1:0]           left_edge_flag;
reg             [1:0]           right_edge_flag;always @(posedge clk or negedge rst_n)
beginif(!rst_n)vsync <= 2'b0;elsebeginif((per_img_href == 1'b1)&&(vcnt == 11'd1)&&(hcnt == 11'b0))vsync[0] <= 1'b1;else if(extend_last_row_cnt == DELAY_NUM + IMG_HDISP)vsync[0] <= 1'b0;elsevsync[0] <= vsync[0];vsync[1] <= vsync[0];end
endalways @(posedge clk or negedge rst_n)
beginif(!rst_n)beginhref             <= 2'b0;top_edge_flag    <= 2'b0;bottom_edge_flag <= 2'b0;left_edge_flag   <= 2'b0;right_edge_flag  <= 2'b0;endelsebeginhref[0]             <= per_img_href & (vcnt > 11'b0) | extend_last_row_en;href[1]             <= href[0];top_edge_flag[0]    <= per_img_href & (vcnt == 11'd1);top_edge_flag[1]    <= top_edge_flag[0];bottom_edge_flag[0] <= extend_last_row_en;bottom_edge_flag[1] <= bottom_edge_flag[0];left_edge_flag[0]   <= per_img_href & (vcnt > 11'b0) & (hcnt == 11'b0) | (extend_last_row_cnt == DELAY_NUM + 1'b1);left_edge_flag[1]   <= left_edge_flag[0];right_edge_flag[0]  <= per_img_href & (vcnt > 11'b0) & (hcnt == IMG_HDISP - 1'b1) | (extend_last_row_cnt == DELAY_NUM + IMG_HDISP);right_edge_flag[1]  <= right_edge_flag[0];end
endassign matrix_img_vsync        = vsync[1];
assign matrix_img_href         = href[1];
assign matrix_top_edge_flag    = top_edge_flag[1];
assign matrix_bottom_edge_flag = bottom_edge_flag[1];
assign matrix_left_edge_flag   = left_edge_flag[1];
assign matrix_right_edge_flag  = right_edge_flag[1];endmodule	

均值算法
module mean_filter_proc
#(
parameter [10:0] IMG_HDISP = 11’d640, // 640*480
parameter [10:0] IMG_VDISP = 11’d480
)
(
input wire clk ,
input wire rst_n ,

//  Image data prepared to be processed
input  wire                 per_img_vsync   ,       //  Prepared Image data vsync valid signal
input  wire                 per_img_href    ,       //  Prepared Image data href vaild  signal
input  wire     [7:0]       per_img_gray    ,       //  Prepared Image brightness input//  Image data has been processed
output reg                  post_img_vsync  ,       //  processed Image data vsync valid signal
output reg                  post_img_href   ,       //  processed Image data href vaild  signal
output reg      [7:0]       post_img_gray           //  processed Image brightness output

);
//----------------------------------------------------------------------
// Generate 8Bit 3X3 Matrix
wire matrix_img_vsync;
wire matrix_img_href;
wire matrix_top_edge_flag;
wire matrix_bottom_edge_flag;
wire matrix_left_edge_flag;
wire matrix_right_edge_flag;
wire [7:0] matrix_p11;
wire [7:0] matrix_p12;
wire [7:0] matrix_p13;
wire [7:0] matrix_p21;
wire [7:0] matrix_p22;
wire [7:0] matrix_p23;
wire [7:0] matrix_p31;
wire [7:0] matrix_p32;
wire [7:0] matrix_p33;

Matrix_Generate_3X3_8Bit
#(
.IMG_HDISP (IMG_HDISP ),
.IMG_VDISP (IMG_VDISP )
)
u_Matrix_Generate_3X3_8Bit
(
// global clock & reset
.clk (clk ),
.rst_n (rst_n ),

//  Image data prepared to be processed
.per_img_vsync          (per_img_vsync          ),      //  Prepared Image data vsync valid signal
.per_img_href           (per_img_href           ),      //  Prepared Image data href vaild  signal
.per_img_gray           (per_img_gray           ),      //  Prepared Image brightness input//  Image data has been processed
.matrix_img_vsync       (matrix_img_vsync       ),      //  processed Image data vsync valid signal
.matrix_img_href        (matrix_img_href        ),      //  processed Image data href vaild  signal
.matrix_top_edge_flag   (matrix_top_edge_flag   ),      //  processed Image top edge
.matrix_bottom_edge_flag(matrix_bottom_edge_flag),      //  processed Image bottom edge
.matrix_left_edge_flag  (matrix_left_edge_flag  ),      //  processed Image left edge
.matrix_right_edge_flag (matrix_right_edge_flag ),      //  processed Image right edge
.matrix_p11             (matrix_p11             ),      //  3X3 Matrix output
.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             )

);

//----------------------------------------------------------------------
// calc sum of [p11,p12,p13;p21,p22,p23;p31,p32,p33]
reg [ 9:0] data_sum1;
reg [ 9:0] data_sum2;
reg [ 9:0] data_sum3;
reg [11:0] data_sum;

always @(posedge clk)
begin
data_sum1 <= matrix_p11 + matrix_p12 + matrix_p13;
data_sum2 <= matrix_p21 + matrix_p22 + matrix_p23;
data_sum3 <= matrix_p31 + matrix_p32 + matrix_p33;
data_sum <= data_sum1 + data_sum2 + data_sum3;
end

//----------------------------------------------------------------------
// avg_data = round(data_sum/9.0) -> avg_data = round(data_sum*3641 >> 15)
reg [22:0] data_mult;

always @(posedge clk)
begin
data_mult <= data_sum * 12’d3641;
end

reg [7:0] avg_data;

always @(posedge clk)
begin
avg_data <= data_mult[22:15] + data_mult[14];
end

//----------------------------------------------------------------------
// lag 4 clocks signal sync
reg [3:0] matrix_img_vsync_r1;
reg [3:0] matrix_img_href_r1;
reg [3:0] matrix_edge_flag_r1;

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
matrix_img_vsync_r1 <= 4’b0;
matrix_img_href_r1 <= 4’b0;
matrix_edge_flag_r1 <= 4’b0;
end
else
begin
matrix_img_vsync_r1 <= {matrix_img_vsync_r1[2:0],matrix_img_vsync};
matrix_img_href_r1 <= {matrix_img_href_r1[2:0],matrix_img_href};
matrix_edge_flag_r1 <= {matrix_edge_flag_r1[2:0],matrix_top_edge_flag | matrix_bottom_edge_flag | matrix_left_edge_flag | matrix_right_edge_flag};
end
end

reg [7:0] matrix_p22_r1 [0:3];

always @(posedge clk)
begin
matrix_p22_r1[0] <= matrix_p22;
matrix_p22_r1[1] <= matrix_p22_r1[0];
matrix_p22_r1[2] <= matrix_p22_r1[1];
matrix_p22_r1[3] <= matrix_p22_r1[2];
end

//----------------------------------------------------------------------
// result output
always @(posedge clk)
begin
if(matrix_edge_flag_r1[3] == 1’b1)
post_img_gray <= matrix_p22_r1[3];
else
post_img_gray <= avg_data;
end

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
post_img_vsync <= 1’b0;
post_img_href <= 1’b0;
end
else
begin
post_img_vsync <= matrix_img_vsync_r1[3];
post_img_href <= matrix_img_href_r1[3];
end
end

endmodule

3.参考资料

1.基于MATLAB与FPGA的图像处理教程 (韩彬)

更多推荐

FPGA图像处理之均值滤波

本文发布于:2024-02-25 18:41:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1699925.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:图像处理   均值   FPGA

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!