FPGA实现图像的空间滤波——均值滤波

FPGA实现图像的空间滤波——均值滤波

空间滤波

         空间滤波的机理通过滤波模版的逐点地移动,在每一点(x,y)处,滤波器在该点的响应通过事先定义的关系来计算。对于线性空间滤波,其响应由滤波器系数与滤波掩模扫过区域的相应像素值的乘积之和给出。

         一般来说在MxN的图像上,用mxn大小的滤波器掩模进行线性滤波由下式给出:

g ( x , y ) = ∑ s = − a a ∑ s = − b b w ( s , t ) f ( x + s , y + t ) g(x,y)=\sum _ { s= -a } ^ { a }\sum _ { s = -b } ^ { b } w(s,t)f(x+s,y+t) g(x,y)=s=aas=bbw(s,t)f(x+s,y+t)
FPGA实现图像的空间滤波——均值滤波_第1张图片
中心处的值由模版和周围值的函数算出计算出并代替原来的值,对整个图像每一个像素点都进行相同的操作,就完成了图像的空间滤波。

平滑空间滤波器

         平滑空间滤波器用于模糊处理和减小噪声。模糊处理经常用于预处理,例如在提取大的目标之前去除图像中的一些琐碎的细节、桥接连线或曲线的缝合。平滑线性空间滤波器的输出响应是包括在滤波掩模邻域内像素的简单平均值。因此这些滤波器也称为均值滤波器。

         一幅MxN的图像经过一个mxn(m和n是奇数)的加权均值滤波器滤波的过程可由下式给出:

g ( x , y ) = ∑ s = − a a ∑ s = − b b w ( s , t ) f ( x + s , y + t ) ∑ s = − a a ∑ s = − b b w ( s , t ) g(x,y)= \frac { \sum _ { s= -a } ^ { a }\sum _ { s = -b } ^ { b } w(s,t)f(x+s,y+t)} { \sum _ { s= -a } ^ { a }\sum _ { s = -b } ^ { b } w(s,t)} g(x,y)=s=aas=bbw(s,t)s=aas=bbw(s,t)f(x+s,y+t)

FPGA实现图像的空间滤波——均值滤波_第2张图片

%matlab仿真滤波
%基于1/16的加权均值滤波

clear
clc
I1=imread('lena.jpg');
I=im2double(I1);
[m,n,c]=size(I);
A=zeros(m,n,c);
%           1   2   1
%   1/16 *  2  4   2
%           1   2   1
%for R
for i=2:m-1
    for j=2:n-1
       A(i,j,1)=I(i-1,j-1,1)+I(i+1,j-1,1)+I(i-1,j+1,1)+I(i+1,j+1,1)+2*I(i+1,j,1)+2*I(i-1,j,1)+2*I(i,j+1,1)+2*I(i,j-1,1)+4*I(i,j,1);
    end
end
%for G
for i=2:m-1
    for j=2:n-1
       A(i,j,2)=I(i-1,j-1,2)+I(i+1,j-1,2)+I(i-1,j+1,2)+I(i+1,j+1,2)+2*I(i+1,j,2)+2*I(i-1,j,2)+2*I(i,j+1,2)+2*I(i,j-1,2)+4*I(i,j,2);
    end
end
%for B
for i=2:m-1
    for j=2:n-1
       A(i,j,3)=I(i-1,j-1,3)+I(i+1,j-1,3)+I(i-1,j+1,3)+I(i+1,j+1,3)+2*I(i+1,j,3)+2*I(i-1,j,3)+2*I(i,j+1,3)+2*I(i,j-1,3)+4*I(i,j,3);
    end
end
B=A/16;
%output
imwrite(B,'lena.tif','tif');
imshow('lena.jpg');title('origin image');figure
imshow('lena.tif');title('image after average filter')

FPGA实现图像的空间滤波——均值滤波_第3张图片
FPGA实现图像的空间滤波——均值滤波_第4张图片

         第一张为原始图像,第二张为经过均值滤波的图像,可以看出滤波后的图像有一些模糊,这是由于均值滤波对图像做了平滑处理,像素值高的像素会被拉低,像素值低的像素会被拉高,趋于一个平均值,由于在图像的人物轮廓边界的值差别较大,经平均值后边界得到平滑,所以平滑滤波会使图像的边界会变得模糊。

//FPGA实现
module VIP_Gray_Mean_Filter
#(
	parameter	[9:0]	IMG_HDISP = 10'd480,	//640*480
	parameter	[9:0]	IMG_VDISP = 10'd272
)
(
	//global clock
	input				clk,  				//100MHz
	input				rst_n,				//global reset

	//Image data prepred to be processd
	input				per_frame_vsync,	//Prepared Image data vsync valid signal
	input				per_frame_href,		//Prepared Image data href vaild  signal
	input				per_frame_clken,	//Prepared Image data output/capture enable clock
	input		[7:0]	per_img_Y,			//Prepared Image brightness input
	
	//Image data has been processd
	output				post_frame_vsync,	//Processed Image data vsync valid signal
	output				post_frame_href,	//Processed Image data href vaild  signal
	output				post_frame_clken,	//Processed Image data output/capture enable clock
	output		[15:0]	post_img_Y			//Processed Image brightness input
);



//----------------------------------------------------
//Generate 8Bit 3X3 Matrix for Video Image Processor.
	//Image data has been processd
wire				matrix_frame_vsync;	//Prepared Image data vsync valid signal
wire				matrix_frame_href;	//Prepared Image data href vaild  signal
wire				matrix_frame_clken;	//Prepared Image data output/capture enable clock	
wire		[7:0]	matrix_p11, matrix_p12, matrix_p13;	//3X3 Matrix output
wire		[7:0]	matrix_p21, matrix_p22, matrix_p23;
wire		[7:0]	matrix_p31, matrix_p32, matrix_p33;
VIP_Matrix_Generate_3X3_8Bit	
#(
	.IMG_HDISP	(IMG_HDISP),	//640*480
	.IMG_VDISP	(IMG_VDISP)
)
u_VIP_Matrix_Generate_3X3_8Bit
(
	//global clock
	.clk					(clk),  				//cmos video pixel clock
	.rst_n					(rst_n),				//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(per_frame_vsync),		//Prepared Image data vsync valid signal
	.per_frame_href			(per_frame_href),		//Prepared Image data href vaild  signal
	.per_frame_clken		(per_frame_clken),		//Prepared Image data output/capture enable clock
	.per_img_Y				(per_img_Y),			//Prepared Image brightness input

	//Image data has been processd
	.matrix_frame_vsync		(matrix_frame_vsync),	//Processed Image data vsync valid signal
	.matrix_frame_href		(matrix_frame_href),	//Processed Image data href vaild  signal
	.matrix_frame_clken		(matrix_frame_clken),	//Processed Image data output/capture enable clock	
	.matrix_p11(matrix_p11),	.matrix_p12(matrix_p12), 	.matrix_p13(matrix_p13),	//3X3 Matrix output
	.matrix_p21(matrix_p21), 	.matrix_p22(matrix_p22), 	.matrix_p23(matrix_p23),
	.matrix_p31(matrix_p31), 	.matrix_p32(matrix_p32), 	.matrix_p33(matrix_p33)
);


//Add you arithmetic here
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//Mean Filter of 3X3 datas, need 2 clock
//Step 1
reg	[10:0]	mean_value1, mean_value2, mean_value3;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
		mean_value1 <= 0;
		mean_value2 <= 0;
		mean_value3 <= 0;
		end
	else
		begin
		mean_value1 <= matrix_p11 + matrix_p12 + matrix_p13;
		mean_value2 <= matrix_p21 + 11'd0	   + matrix_p23;
		mean_value3 <= matrix_p31 + matrix_p32 + matrix_p33;
		end
end


//Step2
reg	[10:0]	mean_value4;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		mean_value4 <= 0;
	else
		mean_value4 <= mean_value1 + mean_value2 + mean_value3;
end
//step3  
reg  [16:0]  post_img_Y1;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
      post_img_Y1 <=16'd0;
    end
    else begin
          post_img_Y1<= {mean_value4[10:6],mean_value4[10:5],mean_value4[10:6]};
    end

end
//------------------------------------------
//lag 2 clocks signal sync  
reg	[2:0]	per_frame_vsync_r;
reg	[2:0]	per_frame_href_r;	
reg	[2:0]	per_frame_clken_r;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
		per_frame_vsync_r <= 0;
		per_frame_href_r <= 0;
		per_frame_clken_r <= 0;
		end
	else
		begin
		per_frame_vsync_r 	<= 	{per_frame_vsync_r[1:0], 	matrix_frame_vsync};
		per_frame_href_r 	<= 	{per_frame_href_r[1:0], 	matrix_frame_href};
		per_frame_clken_r 	<= 	{per_frame_clken_r[1:0], 	matrix_frame_clken};
		end
end
assign	post_frame_vsync 	= 	per_frame_vsync_r[2];
assign	post_frame_href 	= 	per_frame_href_r[2];
assign	post_frame_clken 	= 	per_frame_clken_r[2];
assign	post_img_Y			=	post_frame_href ? post_img_Y1: 16'd0;


endmodule

         FPGA实现时主要要注意的就是数据相加时的字长要增大,运算完后要对数据的高位进行截取,采用流水线的方法实现图像处理的硬件加速。

         本文引用了其他文章资料,如有侵权,联系本人会做出修改。版本1.0,2019.10.20 作者小飞。

你可能感兴趣的:(FPGA数字图像处理)