查看: 2856|回复: 0

(八)灰度图像高斯滤波算法实现

[复制链接]
  • TA的每日心情
    无聊
    2021-4-7 11:23
  • 签到天数: 27 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2020-1-27 23:14:53 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 雪孩爱雪 于 2020-1-27 23:18 编辑

    内容概要
    高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。
    通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身
    和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷
    积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模
    板中心像素点的值。
    一维高斯分布:
    360截图17140306105368.png
    二维高斯分布
    360截图18720115489760.png
    高斯滤波后图像被平滑的程度取决于标准差。它的输出是临域像素的加权平均,同时离
    中心越近的像素权重越高。因此,相对于均值滤波(mean filter)它的平滑效果更柔和,而
    且边缘保留的也更好。
    高斯滤波被用作为平滑滤波器的本质原因是因为它是一个低通滤波器,而且大部份基于
    卷积平滑滤波器都是低通滤波器

    GAUSS 滤波算法克服了边界效应,因而滤波后的图像较好。
    高斯滤波算法实现步骤

    360截图18430705064540.png
    f(x,y)表示(x,y)点的像素值;g(x,y)表示(x,y)点经过高斯滤波处理后的值;
    用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值
    g(x,y)=1/16* (f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)+2f(x-1,y)+4f(x,y) + 2f(x+1,y)+f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1))---(1)
    用模板扫描图像中的每一个像素

    360截图18180715194450.png
    使用高斯滤波模板从屏幕的左上角(从左到右),没扫完一行换下一行
    (从上到下)扫完整个屏幕,最终完成一帧图的高斯滤波。
    FPGA 实现
    首先将 RGB 图像转换成 Gray 图像(见之前的帖子)
    方法 1使用 R/G/B 单通道形成灰度图像进入高斯滤波模块。

    方法 2:使用 RGB 图像转换成 Ycbcr 的图像的 Y 通道形成灰度图像进入高斯
    滤波模块



    要想用实现高斯滤波,必须要先生成3x3阵列,在Xilinx系列里,可以用调用IP核——shift_RAM,具体设置参数如图所示。
    添加IP核
    搜索IP核
    IP核设置
    hift register(RAM-based)ip 主要为了形成三行像素缓存。
    这里Xilinx的shift_ram一次只能生成一行数据,所以我采用两个IP Core和正在输入的一行来生成三行数据
    module line3(
        input clk,
        input [15:0] din,
        input hs_valid_in,
        output [15:0] dout,
        output [15:0] dout_r0,
        output [15:0] dout_r1,
        output [15:0] dout_r2
        );
    line_buff line_buff0(
      .D(din),
       .CLK(clk),
       .CE(hs_valid_in),
       .Q(dout_r0)
    );
    line_buff line_buff1(
      .D(dout_r0),
       .CLK(clk),
       .CE(hs_valid_in),
       .Q(dout_r1)
    );
    line_buff line_buff2(
        .D(dout_r1),
       .CLK(clk),
       .CE(hs_valid_in),
       .Q(dout_r2)
    );
    assign dout = dout_r2;
    endmodule
    高斯滤波算法(需要将图像转为灰度,转为灰度方法见之前发的):


    `timescale 1ns/1ps

    module gaussian_filter_3x3(
           input             clk,
                     input             rst_n,
                     
                     input [15:0]      data_in,
                     input             data_in_en,
                     
                     output  reg [15:0]data_out,
                     output            data_out_en
                     );
                     
    wire [15:0] line0;
    wire [15:0] line1;
    wire [15:0] line2;

    reg [15:0] line0_data0;
    reg [15:0] line0_data1;
    reg [15:0] line0_data2;

    reg [15:0] line1_data0;
    reg [15:0] line1_data1;
    reg [15:0] line1_data2;

    reg [15:0] line2_data0;
    reg [15:0] line2_data1;
    reg [15:0] line2_data2;

    line3 line3x3_inst(
            .clken(data_in_en),
                 .clock(clk),
                 .shiftin(data_in),
                 .shiftout(),
                 .taps0x(line0),
                 .taps1x(line1),
                 .taps2x(line2)
                      );
    //----------------------------------------------------
    // Form an image matrix of three multiplied by three
    //----------------------------------------------------

    always @(posedge clk or negedge rst_n) begin
      if(!rst_n) begin
        line0_data0 <= 16'b0;
             line0_data1 <= 16'b0;
             line0_data2 <= 16'b0;
             
             line1_data0 <= 16'b0;
             line1_data1 <= 16'b0;
             line1_data2 <= 16'b0;
             
             line2_data0 <= 16'b0;
             line2_data1 <= 16'b0;
             line2_data2 <= 16'b0;
      end
      else if(data_in_en) begin
        line0_data0 <= line0;
             line0_data1 <= line0_data0;
             line0_data2 <= line0_data1;
             
             line1_data0 <= line1;
             line1_data1 <= line1_data0;
             line1_data2 <= line1_data1;
             
             line2_data0 <= line2;
             line2_data1 <= line2_data0;
             line2_data2 <= line2_data1;         
      end
    end



    always @(posedge clk or negedge rst_n) begin
      if(!rst_n)
        data_out <= 16'b0;
      else if(data_in_en)
        data_out <= (line0_data0 + line0_data1*2 + line0_data2 + line1_data0*2 + line1_data1*4 + line1_data2*2 + line2_data0 + line2_data1*2 + line2_data2)>>4;
             //data_out <= line2_data1;
      else ;
    end

    endmodule
    我们将lena的照片加入椒盐噪声,如下图:

    然后生成coe文件,导入工程,下载后便可以看到滤波效果。

    cb8e5c5aa89a3333ebfaa9f538858bd.jpg
    (加入椒盐噪声之后产生灰度图像)
    微信图片_20200127231744.jpg
    (滤波之后放大可以看到效果手机拍出来拍不出来)

    至此,基于 FPGA 的三大图像滤波(均值滤波、中值滤波、高斯滤波)处理已经讲解完
    毕,其中的图像处理效果需要大家自己去实验,去对比。手机拍摄出来的毕竟有差距。


    FPGA 在前端捕获到数据后首先要对图像做一个预处理,然后根据噪声的来源,针
    对椒盐噪声进行中值滤波,针对高斯噪声进行高斯滤波处理,均值滤波在图像处理中也很常




    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-28 02:48 , Processed in 0.122776 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.