FPGA学习笔记_图像处理5_FPGA实现灰度图像高斯滤波算法

FPGA学习笔记

图像处理算法

1. 灰度图像高斯滤波算法
   1.1 原理
   1.2 FPGA实现灰度图像高斯滤波算法

1. 灰度图像高斯滤波算法

1.1 原理

  • 高斯滤波:线性平滑滤波,低通滤波器,用于消除高斯噪声
  • 原理:对整幅图进行加权平均,每一个像素点的值,由其本身和领域的其他像素值经过加权平均之后得到。
  • 优点:克服了边界效应,相对于均值滤波平滑效果更柔和,边缘保留的更好。

1.2 FPGA实现灰度图像均值滤波算法
在这里插入图片描述

  • FPGA实现步骤

    1. F(x,y): (x,y) 点的像素值
    2. G(x,y): (x,y)点经过高斯滤波处理后的值
    3. 用模板(或称卷积,掩膜)确定邻域像素的加权平均灰度值代替原中心像素点的值:G(x,y)=(1/16)(f(x-1,y-1)+2f(x,y-i)+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))
    4. 用高斯滤波模板扫描图像的每一个像素
  • FPGA实现方法:
    方法(2种): 1.R/G/B单通道形成灰度图像进入高斯滤波. 2. Ycbcr的图像的Y通道形成灰度图像进入高斯滤波.
    1.R/G/B单通道形成灰度图像进入高斯滤波
    在这里插入图片描述

  1. Ycbcr的图像的Y通道形成灰度图像进入高斯滤波
    在这里插入图片描述
  • Verilog代码
/*
F(x,y): (x,y) 点的像素值
G(x,y): (x,y)点经过高斯滤波处理后的值
1. 用模板(或称卷积,掩膜)确定邻域像素的加权平均灰度值代替原中心像素点的值
G(x,y)=(1/16)*(f(x-1,y-1)+2*f(x,y-i)+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))
2. 用高斯滤波模板扫描图像的每一个像素

*/
module gauss_filter_r0(
	input				clk,
	input				rst_n,
	input		[15:0]	data_in,//输入像素
	input				data_in_en,//LCD显示区使能信号
	
	output	reg	[15:0]	data_out,//输出高斯滤波处理后的像素
	output	wire		data_out_en
);

	wire	[15:0]	r0;
	wire	[15:0]	r1;
	wire	[15:0]	r2;

	reg	[15:0]	r0_c0;	
	reg	[15:0]	r0_c1;	
	reg	[15:0]	r0_c2;
	
	reg	[15:0]	r1_c0;	
	reg	[15:0]	r1_c1;	
	reg	[15:0]	r1_c2;
	
	reg	[15:0]	r2_c0;	
	reg	[15:0]	r2_c1;	
	reg	[15:0]	r2_c2;	
	
	reg				de_reg0;	
	reg				de_reg1;	
	reg				de_reg2;
	reg				de_reg3;	
	
	reg	[31:0]	guass_add;
	reg	[31:0]	guass_reg0;
	reg	[31:0]   guass_reg1;
	reg	[31:0]   guass_reg2;
	
//----3行像素缓存-----------------------------------------
	shifter3_3	shifter3_3(
		.clken(data_in_en),
		.clock(clk),
		.shiftin(data_in),
		.shiftout(),
		.taps0x(r0),
		.taps1x(r1),
		.taps2x(r2)
	);
//-------------------------------------------------------
//----3*3 matrix from image------------------------------
//----r0---------------------------------------------
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			r0_c0	<=	16'd0;
			r0_c1	<=	16'd0;
			r0_c2	<=	16'd0;			
		end
		else if(data_in_en)begin
			r0_c0	<=	r0;
			r0_c1	<=	r0_c0;
			r0_c2	<=	r0_c1;			
		end
	end
//----r1---------------------------------------------
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			r1_c0	<=	16'd0;
			r1_c1	<=	16'd0;
			r1_c2	<=	16'd0;			
		end
		else if(data_in_en)begin
			r1_c0	<=	r1;
			r1_c1	<=	r1_c0;
			r1_c2	<=	r1_c1;			
		end
	end
//----r2---------------------------------------------
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			r2_c0	<=	16'd0;
			r2_c1	<=	16'd0;
			r2_c2	<=	16'd0;			
		end
		else if(data_in_en)begin
			r2_c0	<=	r2;
			r2_c1	<=	r2_c0;
			r2_c2	<=	r2_c1;			
		end
	end
//--------------------------------------------------------
//----Timing----------------------------------------------
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			de_reg0	<=	1'd0;
			de_reg1	<=	1'd0;
			de_reg2	<=	1'd0;
			de_reg3	<=	1'd0;
		end
		else if(data_in_en)begin
			de_reg0	<=	data_in_en;
			de_reg1	<=	de_reg0;
			de_reg2	<=	de_reg1;
			de_reg3	<= de_reg2;
		end
	end
	assign	data_out_en = de_reg3;
//-------------------------------------------------------
//----guass filter---------------------------------------
/*
|(x-1,y-1),(x,y-i),(x+1,y-1) |        |r0_c0,r0_c1,r0_c2 |
|  (x-1,y),  (x,y), (x+1,y)  |  <-->  |r1_c0,r1_c1,r1_c2 |
|(x-1,y+1),(x,y+1),(x+1,y+1) |        |r2_c0,r2_c1,r2_c2 |


高斯滤波公式:G(x,y)=(1/16)*(f(x-1,y-1)+2*f(x,y-i)+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))
*/
//----pipeline-------------------------------------------
//----1. MAC of each line-------------------------
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			guass_reg0	<=	32'd0;
			guass_reg1	<=	32'd0;
			guass_reg2	<=	32'd0;
		end
		else if(data_in_en)begin
			guass_reg0	<=	r0_c0+2*r0_c1+r0_c2;
			guass_reg1	<=	2*r1_c0+4*r1_c1+2*r1_c2;
			guass_reg2	<=	r2_c0+2*r2_c1+r2_c2;
		end
		else;
	end

//----2. ADD all-------------------------------
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			guass_add	<=	32'd0;
		else if(data_in_en)
			guass_add	<= guass_reg0 + guass_reg1 +guass_reg2;
		else;
	
//----3. divide 16-----------------------------
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			data_out	<=	16'd0;
		else if(data_in_en)
			data_out	<= guass_add >>4;

//-------------------------------------------------------
endmodule

  • 结果
    5寸TFT电容触摸显示屏
    图像:800*480像素
    (1). (易烊千玺^^)网络原图:
    在这里插入图片描述
    (2). FPGA显示原图:在这里插入图片描述
    (3). FPGA灰度处理图:在这里插入图片描述
    (4). FPGA均值滤波图:在这里插入图片描述
    (5). FPGA高斯滤波图:在这里插入图片描述

结果分析:

  • 对比于灰度处理图,经过高斯滤波处理后的图像更柔和,平滑效果更好;
  • 对比于均值滤波图,经过高斯滤波处理后的图像很好的保护图像的细节;

参考资料:《FPGA系统设计与验证实战指南》
【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~


猜你喜欢

转载自blog.csdn.net/weixin_50722839/article/details/113843499