文章目录
高斯滤波
高斯模板:
构建高斯金字塔:
采用5*5的模板,且σ = 1 , 1.6 ,2.26,3.2 , 4.5 ,尺度逐渐变大,从而图像更模糊。
后采用9x9的模板,且σ = 1 , 1.6 ,2.26,3.2 , 4.5 ,尺度逐渐变大,从而图像更模糊。
后采用11x11的模板,且σ = 1 , 1.6 ,2.26,3.2 , 4.5 ,尺度逐渐变大,从而图像更模糊。
后采用15x15的模板,且σ = 1 , 1.6 ,2.26,3.2 , 4.5 ,尺度逐渐变大,从而图像更模糊。
后采用19x19的模板,且σ = 1 , 1.6 ,2.26,3.2 , 4.5 ,尺度逐渐变大,从而图像更模糊。
最终形成高斯金字塔。
clear;
k=1;
row = 2*k+1; %模板长度
col = 2*k+1;
sigma2=0.8; %方差
for i=1 : row
for j=1 : col
fenzi=double((i-k-1)^2+(j-k-1)^2);
A(i,j)=exp(-fenzi/(2*sigma2*sigma2))/(2*pi*sigma2*sigma2);
end
end
A %显示小数形式
C=floor(A.*(1/A(1,1))); %左上角化为1
得到55窗口,sigma = 1的模板:
计算的时候我们在前面乘以55窗口内数据的总和进行归一化,免去亮度的影响。
依次采用该代码计算即可。
高斯滤波具体实现
整体RTL
1、计算高斯滤波模板
取尺寸为55,99,1111,1515,19*19.
同时每个尺寸种σ=1,1.6,2.26,3.2,4.5
以形成高斯金字塔
模板尺寸55,σ = 1。运行上面高斯滤波模板生成的代码,得到矩阵C,同时保证矩阵内的数据相加为1,这样在处理的时候就能免去亮度的影响。得到模板尺寸55,σ = 1的高斯模板如下:
得到模板尺寸5*5,σ = 1.6的高斯模板如下
……修改参数即可获得不同的高斯滤波模板。
2、matlab进行处理,为图片加入高斯噪声
并将加入高斯噪声的灰度图显示并保存,将高斯去噪后的图显示并保存。
clc;
clear all;
close all;
RGB= imread('1.bmp'); %读取图片
g=imnoise (RGB,'gaussian',0.2); %添加高斯噪声
gray = rgb2gray(g); %灰度图
Gauss_3x3 = fspecial('gaussian',3,0.8); %sigma=2的3*3高斯模板
Gauss = imfilter(gray, Gauss_3x3); %高斯滤波
subplot(2,1,1); imshow(gray); title('加入高斯噪声的灰度图');
subplot(2,1,2); imshow(Gauss); title('高斯滤波');
imwrite (gray,'含高斯噪声的灰度图.bmp');
imwrite (Gauss,'高斯滤波.bmp');
3、FPGA实现高斯滤波
将含高斯噪声的灰度图(左)放入到高斯滤波工程的img文件夹,命名为1
5*5 shift register ip核
4个taps+shiftin刚好构成5列,同时一个taps中有一行640个数据。
5*5窗口生成
module filter_5x5(
input clk,
input rst_n,
input gray_de,
input [7:0] iData,
output filter_de,
//5*5模板数据
output reg [7:0] oData_11, oData_12, oData_13, oData_14, oData_15,
output reg [7:0] oData_21, oData_22, oData_23, oData_24, oData_25,
output reg [7:0] oData_31, oData_32, oData_33, oData_34, oData_35,
output reg [7:0] oData_41, oData_42, oData_43, oData_44, oData_45,
output reg [7:0] oData_51, oData_52, oData_53, oData_54, oData_55
);
reg [1:0] de_shift;
reg [7:0] row5_data;
wire[7:0] row4_data,row3_data,row2_data,row1_data;
//移位寄存器实现四行数据缓存
shift_register u1(
.clken(gray_de),
.clock(clk),
.shiftin(row5_data),
.taps0x(row4_data),
.taps1x(row3_data),
.taps2x(row2_data),
.taps3x(row1_data),
.shiftout()
);
// 将输入数据寄存作为第五行起始数据,同时也作为行缓存的输入
always @(posedge clk, negedge rst_n) begin
if(!rst_n)
row5_data <= 0;
else if(gray_de)
row5_data <= iData;
else
row5_data <= 0;
end
// 获取5*5卷积模板
always @(posedge clk, negedge rst_n) begin
if(!rst_n) begin
{oData_11, oData_12, oData_13, oData_14, oData_15} <= 1'b0;
{oData_21, oData_22, oData_23, oData_24, oData_25} <= 1'b0;
{oData_31, oData_32, oData_33, oData_34, oData_35} <= 1'b0;
{oData_41, oData_42, oData_43, oData_44, oData_45} <= 1'b0;
{oData_51, oData_52, oData_53, oData_54, oData_55} <= 1'b0;
end
else if(gray_de) begin
{oData_11, oData_12, oData_13, oData_14, oData_15} <= {oData_12, oData_13, oData_14, oData_15, row1_data};
{oData_21, oData_22, oData_23, oData_24, oData_25} <= {oData_22, oData_23, oData_24, oData_25, row2_data};
{oData_31, oData_32, oData_33, oData_34, oData_35} <= {oData_32, oData_33, oData_34, oData_35, row3_data};
{oData_41, oData_42, oData_43, oData_44, oData_45} <= {oData_42, oData_43, oData_44, oData_45, row4_data};
{oData_51, oData_52, oData_53, oData_54, oData_55} <= {oData_52, oData_53, oData_54, oData_55, row5_data};
end
else begin
{oData_11, oData_12, oData_13, oData_14, oData_15} <= 1'b0;
{oData_21, oData_22, oData_23, oData_24, oData_25} <= 1'b0;
{oData_31, oData_32, oData_33, oData_34, oData_35} <= 1'b0;
{oData_41, oData_42, oData_43, oData_44, oData_45} <= 1'b0;
{oData_51, oData_52, oData_53, oData_54, oData_55} <= 1'b0;
end
end
// 打两拍输出
always @(posedge clk, negedge rst_n) begin
if(!rst_n)begin
de_shift <= 2'b00;
end
else begin
de_shift <= {de_shift[0], gray_de};
end
end
assign filter_de = de_shift[1];
endmodule
高斯滤波:
module gaussian_filter(
input clk,
input rst_n,
input wire iValid,
//模板生成模块生成的5*5窗口数据
input [7:0] filter_11, filter_12, filter_13, filter_14, filter_15,
input [7:0] filter_21, filter_22, filter_23, filter_24, filter_25,
input [7:0] filter_31, filter_32, filter_33, filter_34, filter_35,
input [7:0] filter_41, filter_42, filter_43, filter_44, filter_45,
input [7:0] filter_51, filter_52, filter_53, filter_54, filter_55,
output gaussian_de ,//de同步信号
output wire [7:0] gaussian_data // 高斯卷积:加权平均后的值
);
reg [3:0] de_shift1 ;
reg [13:0] g1,g5;
reg [15:0] g2,g4;
reg [16:0] g3;
reg [18:0] g;
reg [7:0] g_data;
//---------------------------------------------------
// 高斯滤波流水线
//---------------------------------------------------
//clk1,进行所有行的乘加法
always @ (posedge clk or negedge rst_n)
if(!rst_n) begin
g1 <= 1'b0;
g2 <= 1'b0;
g3 <= 1'b0;
g4 <= 1'b0;
g5 <= 1'b0;
end
else begin
g1 <= filter_11 *3 + filter_12 *12 + filter_13 *21 + filter_14 *12 + filter_15 *3 ;
g2 <= filter_21 *12 + filter_22 *60 + filter_23 *99 + filter_24 *60 + filter_25 *12;
g3 <= filter_31 *21 + filter_32 *99 + filter_33 *162 + filter_34 *99 + filter_35 *21;
g4 <= filter_41 *12 + filter_42 *60 + filter_43 *99 + filter_44 *60 + filter_45 *12;
g5 <= filter_51 *3 + filter_52 *12 + filter_53 *21 + filter_54 *12 + filter_55 *3 ;
end
//clk2,三行得到的值相加,完成5*5窗口内的加权计算
always @ (posedge clk or negedge rst_n)
if(!rst_n)
g <= 1'b0;
else
g <= g1 + g2 +g3 +g4 +g5;
// clk3,移位操作,除以1023,则右移10位,或者取高8位
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
g_data <= 1'd0;
end
else begin
g_data <= g[17:10];
end
end
assign gaussian_data = g_data;
// 打拍做同步
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
de_shift1 <= 4'b0;
end
else begin
de_shift1 <= {de_shift1[2:0], iValid};
end
end
assign gaussian_de = de_shift1[3];
endmodule
波形:
FPGA效果图
右图是高斯滤波后的图,可看到图像变模糊。
matlab效果图: