首页->【FPGA摄像头图像开发联盟】

529 0

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

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

//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)

);

不过相对于3*3像素阵列的生成而言,均值滤波的算法实现反而难度小的多,只是技巧性的问题。

P11

P12

P13

P21

 

P23

P31

P32

P33

继续分析上面这个表格。其实HDL完全有这个能力直接计算8个值相加的均值,不过为了提升电路的速度,Bingo建议我们需要通过以面积换速度的方式来实现。So这里需要3个步骤:

(1)    分别计算3行中相关像素的和,相关HDL代码如下

//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

(2)    计算(1)中三个结果的和

//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

在(2)运算后,我们不能急着用除法去实现均值的运算。记住,能用移位替换的,绝对不用乘除法来实现。这里8个像素,即除以8,可以方便的用右移动3Bit来实现。不过这里更方便的办法是,直接提取mean_value4[10:3]

这一步我们不单独作为一个Step,而是直接作为结果输出。分析前面的运算,总共耗费了2个时钟,因此需要将行场信号、像素读取信号偏移2个时钟,同时像素时钟,根据行信号使能,直接读取mean_value4[10:3],如下所示:

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

//lag 2 clocks signal sync 

reg   [1:0]   per_frame_vsync_r;

reg   [1:0]   per_frame_href_r;  

reg   [1: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[0], matrix_frame_vsync};

      per_frame_href_r    <= {per_frame_href_r[0],   matrix_frame_href};

      per_frame_clken_r   <= {per_frame_clken_r[0], matrix_frame_clken};

      end

end

assign    post_frame_vsync    =   per_frame_vsync_r[1];

assign    post_frame_href     =   per_frame_href_r[1];

assign    post_frame_clken    =   per_frame_clken_r[1];

assign    post_img_Y          =   post_frame_href ? mean_value4[10:3] : 8'd0;

这样,我们便得到了运算后的VIP时序,实现了均值滤波算法,其Modelsim仿真图如下所示:

最后,在Video_Image_Processor顶层VIP文件中例化VIP_Gray_Mean_Filter算法模块,完成算法的添加,如下所示:

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

//Gray Image mean filter for better picture quality.

VIP_Gray_Mean_Filter

#(

  .IMG_HDISP  (IMG_HDISP),    //640*480

  .IMG_VDISP  (IMG_VDISP)

)

u_VIP_Gray_Mean_Filter

(

u_VIP_Gray_Mean_Filter

(

  //global clock

  .clk                    (clk),         

  .rst_n                  (rst_n),           

 

  //Image data prepred to be processd

  .per_frame_vsync        (per_frame_vsync), 

  .per_frame_href         (per_frame_href),  

  .per_frame_clken        (per_frame_clken), 

  .per_img_Y              (per_img_Y),       

 

  //Image data has been processd

  .post_frame_vsync       (post_frame_vsync),

  .post_frame_href        (post_frame_href), 

  .post_frame_clken       (post_frame_clken),

  .post_img_Y             (post_img_Y)       

);

在经过前面几张的磨练,外部框架我们已经成熟的一塌糊涂了。这里直接全编译,下载jic文件,通过USB_Camera_VIP_Panel观察采集到的图像,对比如下所示:

上图(左)为前面YCbCr直接得到的Y灰度视频显示,上图(右)为经过了均值滤波算法后的图像。仔细一看,右图与作图相比,明显丧失了部分细节,图像变得模糊了。这是由于均值滤波的效果/不足,滤除了部分噪声的同步,缺失了更多的细节。

在图像处理中,滤波有很多种算法,均值滤波只是最简单的其中一种而已。本章的目的不仅仅在于均值滤波的实现,更重要的是3*3像素阵列生成的方案、算法实现的技巧,以及整个VIP的框架等。希望读者能够仔细研究分析这一节,包括USB_OV7725_Gray_Mean_Filter Quartus II工程,以及Video_Image_Processor_TB Modelsim仿真测试。

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

楼主可见