FPGA实现图像的二值形态学滤波:边界提取

  轮廓是对物体形状的有力描述,对图像分析和识别十分有用。通过边界提取算法可以得到物体的边界轮廓。

  二值图像的边界提取主要基于黑白区域的边界查找,和许多边界查找算法相比它适合于二值图像。

  边界提取的算法比较简单,以黑色 0 作为背景,白色 1 作为提取。以 3x3 模板为例,9 个像素都为 0 或 1 时输出为 0,否则为 1 。如图所示:

 

一、FPGA实现

  算法比较简单,直接上代码吧。

  1 module Boundary
  2 //========================< 端口 >==========================================
  3 (
  4 input   wire                clk                     ,
  5 input   wire                rst_n                   ,
  6 //input ---------------------------------------------
  7 input   wire                RGB_de                  ,
  8 input   wire                RGB_hsync               ,
  9 input   wire                RGB_vsync               ,
 10 input   wire    [15:0]      RGB_data                ,
 11 //output --------------------------------------------
 12 output  wire                boundary_de             ,
 13 output  wire                boundary_hsync          ,
 14 output  wire                boundary_vsync          ,
 15 output  reg     [15:0]      boundary_data
 16 );
 17 //========================< 信号 >==========================================
 18 //matrix_3x3 ----------------------------------------
 19 wire    [15:0]              matrix_11               ;
 20 wire    [15:0]              matrix_12               ;
 21 wire    [15:0]              matrix_13               ;
 22 wire    [15:0]              matrix_21               ;
 23 wire    [15:0]              matrix_22               ;
 24 wire    [15:0]              matrix_23               ;
 25 wire    [15:0]              matrix_31               ;
 26 wire    [15:0]              matrix_32               ;
 27 wire    [15:0]              matrix_33               ;
 28 //同步 ----------------------------------------------
 29 reg     [ 1:0]              RGB_de_r                ;
 30 reg     [ 1:0]              RGB_hsync_r             ;
 31 reg     [ 1:0]              RGB_vsync_r             ;
 32 //==========================================================================
 33 //==    matrix_3x3,生成3x3矩阵,输入和使能需对齐,耗费1clk
 34 //==========================================================================
 35 //--------------------------------------------------- 矩阵顺序
 36 //        {matrix_11, matrix_12, matrix_13}
 37 //        {matrix_21, matrix_22, matrix_23}
 38 //        {matrix_31, matrix_32, matrix_33}
 39 //--------------------------------------------------- 模块例化
 40 matrix_3x3_16bit
 41 #(
 42     .COL                    (480                    ),
 43     .ROW                    (272                    )
 44 )
 45 u_matrix_3x3_16bit
 46 (
 47     .clk                    (clk                    ),
 48     .rst_n                  (rst_n                  ),
 49     .din_vld                (RGB_de                 ),
 50     .din                    (RGB_data               ),
 51     .matrix_11              (matrix_11              ),
 52     .matrix_12              (matrix_12              ),
 53     .matrix_13              (matrix_13              ),
 54     .matrix_21              (matrix_21              ),
 55     .matrix_22              (matrix_22              ),
 56     .matrix_23              (matrix_23              ),
 57     .matrix_31              (matrix_31              ),
 58     .matrix_32              (matrix_32              ),
 59     .matrix_33              (matrix_33              )
 60 );
 61 //==========================================================================
 62 //==    边缘提取,耗费1clk
 63 //==========================================================================
 64 always @ (posedge clk or negedge rst_n)begin
 65     if(!rst_n)begin
 66         boundary_data <= 16'h0000;
 67     end
 68     else if((matrix_11 == 16'h0000) && (matrix_12 == 16'h0000) && (matrix_13 == 16'h0000) &&
 69             (matrix_21 == 16'h0000) && (matrix_22 == 16'h0000) && (matrix_23 == 16'h0000) &&
 70             (matrix_31 == 16'h0000) && (matrix_32 == 16'h0000) && (matrix_33 == 16'h0000)
 71             ) begin
 72                             boundary_data <= 16'hffff;
 73     end
 74     else if((matrix_11 == 16'hffff) && (matrix_12 == 16'hffff) && (matrix_13 == 16'hffff) &&
 75             (matrix_21 == 16'hffff) && (matrix_22 == 16'hffff) && (matrix_23 == 16'hffff) &&
 76             (matrix_31 == 16'hffff) && (matrix_32 == 16'hffff) && (matrix_33 == 16'hffff)
 77             ) begin
 78                             boundary_data <= 16'hffff;
 79     end
 80     else begin
 81         boundary_data <= 16'h0000;
 82     end
 83 end
 84 //==========================================================================
 85 //==    信号同步
 86 //==========================================================================
 87 always @(posedge clk or negedge rst_n) begin
 88     if(!rst_n) begin
 89         RGB_de_r    <= 2'b0;
 90         RGB_hsync_r <= 2'b0;
 91         RGB_vsync_r <= 2'b0;
 92     end
 93     else begin  
 94         RGB_de_r    <= {RGB_de_r[0],    RGB_de};
 95         RGB_hsync_r <= {RGB_hsync_r[0], RGB_hsync};
 96         RGB_vsync_r <= {RGB_vsync_r[0], RGB_vsync};
 97     end
 98 end
 99 
100 assign boundary_de    = RGB_de_r[1];
101 assign boundary_hsync = RGB_hsync_r[1];
102 assign boundary_vsync = RGB_vsync_r[1];
103     
104 
105 
106 endmodule

 

二、上板验证

   输入找了张二值图片,如果没有二值图片,可以在边界提取前自己写一下阈值判断即可。

  二值原图:

  边界提取后:

  由实验结果可知,边界提取成功,外部的白色和内部的黑色都变为了白色,只有边界处是黑色。

 

参考资料:[1] Opens Lee:FPGA开源工作室(公众号)

posted @ 2020-03-23 13:05  咸鱼IC  阅读(2251)  评论(0编辑  收藏  举报