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開源工作室(公眾號)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM