CrazyBingo

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

0
阅读(226) 评论(0)

这一节忘了,今天补上!


????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算法实现的精髓,才有继续往下看的意义!!!