輪廓是對物體形狀的有力描述,對圖像分析和識別十分有用。通過邊界提取算法可以得到物體的邊界輪廓。
二值圖像的邊界提取主要基於黑白區域的邊界查找,和許多邊界查找算法相比它適合於二值圖像。
邊界提取的算法比較簡單,以黑色 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開源工作室(公眾號)
