本帖最后由 雪孩爱雪 于 2020-1-27 23:18 编辑
内容概要
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。
通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身
和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷
积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模
板中心像素点的值。
一维高斯分布:
二维高斯分布
高斯滤波后图像被平滑的程度取决于标准差。它的输出是临域像素的加权平均,同时离
中心越近的像素权重越高。因此,相对于均值滤波(mean filter)它的平滑效果更柔和,而
且边缘保留的也更好。
高斯滤波被用作为平滑滤波器的本质原因是因为它是一个低通滤波器,而且大部份基于
卷积平滑滤波器都是低通滤波器
GAUSS 滤波算法克服了边界效应,因而滤波后的图像较好。
高斯滤波算法实现步骤
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)
用模板扫描图像中的每一个像素
使用高斯滤波模板从屏幕的左上角(从左到右),没扫完一行换下一行
(从上到下)扫完整个屏幕,最终完成一帧图的高斯滤波。
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文件,导入工程,下载后便可以看到滤波效果。
(加入椒盐噪声之后产生灰度图像) (滤波之后放大可以看到效果手机拍出来拍不出来)
至此,基于 FPGA 的三大图像滤波(均值滤波、中值滤波、高斯滤波)处理已经讲解完
毕,其中的图像处理效果需要大家自己去实验,去对比。手机拍摄出来的毕竟有差距。
FPGA 在前端捕获到数据后首先要对图像做一个预处理,然后根据噪声的来源,针
对椒盐噪声进行中值滤波,针对高斯噪声进行高斯滤波处理,均值滤波在图像处理中也很常
见
|