CrazyBingo

【连载7.3.4.】Median_Filter均值滤波算法的实现

0
阅读(3697)

这一节忘了,今天补上!


ChinaAET《电子应用技术》出版过一篇值得参考的《基于FPGA的实时中值滤波器的硬件实现》,该文采用FPGA+SRAM实现了实时中值滤波,思维值得参考(当然Bingo认为实时实现仅用Shift_RAM就够用)。Okay,转移话题,我们现在的重点是如何快速求得9个值的均值,该论文介绍了某种快速排序法,如下图所示:

3.jpg

从图中可知,首先对,每行的3个像素进行排序,接着提取三个最大值中的最小值,最小值中的最大值,以及中值中的中值;最后再在得到的三个值中,提取中间值,得到最后的结果。整个计算耗费了3个clk,而不需要冒泡法去实现,时间上非常的节省。

在前面经过VIP_Matrix_Generate_3X3_8Bit模块的设计,花了九牛二虎之力,我们终于得到了梦想中的3*3像素阵列,每个像素为8Bit深度。此时开始设计实现均值滤波算法。

(1)首先分别对每行3个像素进行排序,Verilog HDL的实现,由于并行特性,我们只需要一个时钟,实现如下:


module Sort3

(

input clk,

input rst_n,

input [7:0] data1, data2, data3,

output reg [7:0] max_data, mid_data, min_data

);

//-----------------------------------

//Sort of 3 datas

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

max_data <= 0;

mid_data <= 0;

min_data <= 0;

end

else

begin

//get the max value

if(data1 >= data2 && data1 >= data3)

max_data <= data1;

else if(data2 >= data1 && data2 >= data3)

max_data <= data2;

else//(data3 >= data1 && data3 >= data2)

max_data <= data3;

//get the mid value

if((data1 >= data2 && data1 <= data3) || (data1 >= data3 && data1 <= data2))

mid_data <= data1;

else if((data2 >= data1 && data2 <= data3) || (data2 >= data3 && data2 <= data1))

mid_data <= data2;

else//((data3 >= data1 && data3 <= data2) || (data3 >= data2 && data3 <= data1))

mid_data <= data3;

//ge the min value

if(data1 <= data2 && data1 <= data3)

min_data <= data1;

else if(data2 <= data1 && data2 <= data3)

min_data <= data2;

else//(data3 <= data1 && data3 <= data2)

min_data <= data3;

end

end

上述电路实现了第一步的运算,新建Median_Filter_3X3.v,例化Sort3如下:


//Step1

wire [7:0] max_data1, mid_data1, min_data1;

Sort3 u_Sort3_1

(

.clk (clk),

.rst_n (rst_n),

.data1 (data11),

.data2 (data12),

.data3 (data13),

.max_data (max_data1),

.mid_data (mid_data1),

.min_data (min_data1)

);

(2)接着,对三行像素取得的排序进行处理,即提取三个最大值中的最小值,三个最小值中的最大值,以及三个中间值的中间值。这里直接例化Sort3模块即可,如下所示:


//Step2

wire [7:0] max_min_data, mid_mid_data, min_max_data;

Sort3 u_Sort3_4

(

.clk (clk),

.rst_n (rst_n),

.data1 (max_data1),

.data2 (max_data2),

.data3 (max_data3),

.max_data (),

.mid_data (),

.min_data (max_min_data)

);

Sort3 u_Sort3_5

(

.clk (clk),

.rst_n (rst_n),

.data1 (mid_data1),

.data2 (mid_data2),

.data3 (mid_data3),

.max_data (),

.mid_data (mid_mid_data),

.min_data ()

);

Sort3 u_Sort3_6

(

.clk (clk),

.rst_n (rst_n),

.data1 (min_data1),

.data2 (min_data2),

.data3 (min_data3),

.max_data (min_max_data),

.mid_data (),

.min_data ()

);

(3)最后,将(2)中得到的三个值,再次取中值,求得最终9个像素的中值,如下:


//step3

Sort3 u_Sort3_7

(

.clk (clk),

.rst_n (rst_n),

.data1 (max_min_data),

.data2 (mid_mid_data),

.data3 (min_max_data),

.max_data (),

.mid_data (target_data),

.min_data ()

);

Okay,从(1)-(3),我们花费了3个clock,完成了3*3像素阵列的中值提取。这三个步骤的RTL图如下所示,输入9个像素,输出目标中值像素:

4.jpg

最后在VIP_Gray_Median_Filter.v中的中值提取例化如下:


//Median Filter of 3X3 datas, need 3 clock

wire [7:0] mid_value;

Median_Filter_3X3 u_Median_Filter_3X3

(

.clk (clk),

.rst_n (rst_n),

//ROW1

.data11 (matrix_p11),

.data12 (matrix_p12),

.data13 (matrix_p13),

//ROW2

.data21 (matrix_p21),

.data22 (matrix_p22),

.data23 (matrix_p23),

//ROW3

.data31 (matrix_p31),

.data32 (matrix_p32),

.data33 (matrix_p33),

.target_data (mid_value)

);

既然耗费了3个时钟,那行场、像素使能也需要相应的移动3个时钟,来保持同步,这一点非常的重要,如下:


//------------------------------------------

//lag 3 clocks signal sync

reg [2:0] per_frame_vsync_r;

reg [2:0] per_frame_href_r;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

per_frame_vsync_r <= 0;

per_frame_href_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};

end

end

assign post_frame_vsync = per_frame_vsync_r[2];

assign post_frame_href = per_frame_href_r[2];

assign post_img_Gray = post_frame_href ? mid_value : 8'd0;


最后,给出中值滤波的Modelsim仿真图,如下图所示(新架构没有*_clken):

5.jpg

在前面已经搞定3*3的基础上,实现个中值滤波已经非常轻松了,当然前提是您已经掌握了这些设计内容。在VIP_Image_Processor中例化VIP_Gray_Median_Filter,如下所示:


//--------------------------------------

//Gray Image median filter for better picture quality.

wire post3_frame_vsync; //Processed Image data vsync valid signal

wire post3_frame_href; //Processed Image data href vaild signal

wire [7:0] post3_img_Gray; //Processed Image Gray output

VIP_Gray_Median_Filter

#(

.IMG_HDISP (IMG_HDISP), //640*480

.IMG_VDISP (IMG_VDISP)

)

u_VIP_Gray_Median_Filter

(

//global clock

.clk (clk), //cmos video pixel clock

.rst_n (rst_n), //global reset

//Image data prepred to be processd

.per_frame_vsync (post2_frame_vsync), //Prepared Image data vsync valid signal

.per_frame_href (post2_frame_href), //Prepared Image data href vaild signal

.per_img_Gray (post2_img_Gray), //Prepared Image brightness input

//Image data has been processd

.post_frame_vsync (post3_frame_vsync), //Processed Image data vsync valid signal

.post_frame_href (post3_frame_href), //Processed Image data href vaild signal

.post_img_Gray (post3_img_Gray) //Processed Image brightness output

);

`else

assign post3_frame_vsync = post2_frame_vsync;

assign post3_frame_href = post2_frame_href;

assign post3_img_Gray = post2_img_Gray;

最后,全编译、生成下载jic文件,在VGA或者PC上位机上观察处理后的视频,如下所示:

6.jpg

上图左为原始灰度图像,上图右为中值滤波后的图像,可见中值滤波后的图像相对暗了一点,因为最大值被舍去了。但相对于均值滤波而言,中值滤波在滤除噪声的基础上,有效的保存了细节。

此外,顺便说说均值滤波和中值滤波的效果区别,这里对比一下如下图:

7.jpg

上图左为均值滤波图像,上图右为中值滤波后的图像。从图分析,可见均值滤波后的图像,较中值滤波处理的图像,模糊而又丧失了细节。对于椒盐噪声类的处理,中值滤波的优势要比均值滤波大。

此正如前面说的,图像处理中滤波算法有很多,但是万变不离其宗,掌握了最基本的图像处理,更多的模板算法处理方式,也就是移植与实现的问题。Bingo在此介绍了最基本的中值滤波算法的FPGA实现,更典型、富有针对性、更NB的滤波算法,有待读者自己去研究实现!

VIP图像处理,让世界变得更精彩!

郑重声明:只有100%掌握了这一章,才能了解Bingo VIP算法实现的精髓,才有继续往下看的意义!!!

Baidu
map