FPGA图像处理-均值滤波

简介

上一篇博客介绍了如何在FPGA中利用shift-ram实现行缓存,然后得到3x3卷积模板,这回就来利用这个3x3窗口进行均值滤波。
均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标象素为中心的周围 8 个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。
在这里插入图片描述
output = (p11 + p12 + p13 + p21 + p23 + p31 + p32 + p33) / 8
根据公式,可以将其分解为三级流水线:

  • 第一级处理3x3窗口每一行的加法
  • 第二级处理全部加法
  • 第三级处理移位,即除以8

模块简介

为了简单起见,输入输出都是valid+data形式:

module mean_filter(
    input clk,
    input rst_n,
    
    input iValid,
    input [7:0] iData,

    output oValid,
    output [7:0] oData
);

均值滤波算法的实现

获取3x3卷积模板

上一篇博客有介绍如何获取3x3卷积模板,感兴趣的可以看看
需要注意获取3x3卷积模板消耗了2时钟周期。

filter_3x3 inst_filter_3x3(
    .clk      (clk),
    .rst_n    (rst_n),
    .iValid   (iValid),
    .iData    (iData),
    .oValid   (filter_oValid),
    .oData_11 (filter_11), .oData_12 (filter_12), .oData_13 (filter_13),
    .oData_21 (filter_21), .oData_22 (filter_22), .oData_23 (filter_23),
    .oData_31 (filter_31), .oData_32 (filter_32), .oData_33 (filter_33)
);

第一级流水线:处理窗口每一行的和

// 3x3模板的每一行的和
reg [10:0] add_1, add_2, add_3;

always @(posedge clk, negedge rst_n) begin
    if(!rst_n) begin
        add_1 <= 0;
        add_2 <= 0;
        add_3 <= 0;
    end else begin
        add_1 <= filter_11 + filter_12 + filter_13;
        add_2 <= filter_21 + filter_23;             // 中心值不参与运算
        add_3 <= filter_31 + filter_32 + filter_33;
    end
end

第二级流水线:将窗口每一行的和相加得到总和

// 3x3模板的总和
reg [10:0] add_all;

// step2 加法运算,总和
always @(posedge clk, negedge rst_n) begin
    if(!rst_n)
        add_all <= 0;
    else
        add_all <= add_1 + add_2 + add_3;
end

第三级流水线:移位得到均值结果

// 3x3模板总和/8
reg [7:0] mean_value;

// 右移3位即除以8,得出均值
always @(posedge clk, negedge rst_n) begin
    if(!rst_n)
        mean_value <= 0;
    else
        mean_value <= add_all[10:3];
end

获取3x3卷积模板消耗了2时钟周期,均值滤波消耗了3时钟周期,所以输出值延后输入值5个时钟周期,oValid信号也要进行延迟,比iValid慢5个时钟周期。

testbench

和之前类似,仿真3行像素,每行640个像素点。

`timescale 1ps/1ps
module mean_filter_tb;
    reg clk = 1'b1;
    always #10 clk = ~clk;
    reg rst_n = 1'b0;

    reg iValid = 1'b0;
    reg [7:0] iData = 0;

    wire oValid;
    wire [7:0] oData;

    initial begin
        #20 rst_n <= 1'b1;
        #20 iValid <= 1'b1;

        // 第一行数据
        repeat(640) begin
            iData <= $random;
            #20;
        end
        iValid <= 1'b0;

		// 第二行数据
        #100 iValid <= 1'b1;
        repeat(640) begin
            iData <= $random;
            #20;
        end
        iValid <= 1'b0;

		// 第三行数据
        #100 iValid <= 1'b1;
        repeat(640) begin
            iData <= $random;
            #20;
        end
        #500 $stop;
    end

    mean_filter inst_mean_filter(
        .clk    (clk),
        .rst_n  (rst_n),
        .iValid (iValid),
        .iData  (iData),
        .oValid (oValid),
        .oData  (oData)
    );
endmodule

波形分析

第一行前3个像素为36,129,9
在这里插入图片描述
第二行前3个像素为235,248,242
在这里插入图片描述
第三行前三个像素为121,205,146
在这里插入图片描述
第一个完整模板的均值:(36 + 129 + 9 + 235 + 242 + 121 + 205 + 146) / 8 = 140
模板中间的像素248不参与计算,当146进入模板后的第五个时钟周期,输出了140,验证正确。
下一个均值:(129 + 9 + 99 + 248 + 137 + 205 + 146 + 69) / 8 = 130
模板中间的242不参与计算,可以看到,140后面输出的就是130,验证正确。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
基于FPGA的中值滤波算法的设计与实现 摘 要 在图像的采集、传输和记录等过程中,由于受到多方面因素的影响,图像信号会不可避免地受到椒盐噪声的污染,这将会严重影响图像的后期分析和识别等处理,因此有必要用中值滤波器对图像的椒盐噪声进行滤波预处理。 实际应用中,对滤波器件不仅要求能够将图像中的椒盐噪声滤除,满足图像处理的实时性要求,而且还要求能够很好地保护图像细节,避免滤波后图像变得模糊。针对传统的快速中值滤波算法在滤除图像椒盐噪声时存在图像细节模糊的缺陷,本文提出了一种基于FPGA的改进的快速中值滤波算法。该算法在中值滤波过程中,首先根据设定的阈值判断滤波窗口的中心像素点的是否为噪声点,若是噪声点,就利用快速中值滤波算法求出中值并替换中心点的原像素值,若不是噪声点,就不进行中值滤波处理。利用MATLAB软件对该算法进行仿真的结果表明,该算法具有良好的去噪和图像细节保持的能力。 在该算法FPGA实现过程中,充分利用FPGA硬件的并行性,并且采用流水线技术,提高了图像滤波的处理速度。FPGA硬件实现的结果表明,该算法与传统的快速滤波算法相比,不仅能够满足图像处理的实时性要求,而且还能在滤除图像椒盐噪声的同时,避免滤波后图像变得模糊的缺陷,达到了保护原始图像细节的目的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值