之前上一篇文章寫了如何將圖片進行灰度化處理,這篇文章參考CB的文章簡單的介紹一下如何進行sobel邊緣化處理。
邊緣 : 周圍像素灰度急劇變化的那些像素的集合,它是圖像最基本的特征
公式 :
這里Gx和Gy分別代表橫向及縱向邊緣檢測的圖像灰度值,該點灰度值大小為G,式子里A代表經過灰度
處理的原始圖像,最終計算出來的結果和設定的閾值進行比較如果大於閾值顯示一個顏色,否則就顯示其他
顏色即可。
采用流水線的方法:
1、移位,A是一個3X3的矩陣,需要不斷的刷新,我用的是9個寄存器,每一個時鍾就刷新一次。
2、計算Gx 和Gy,矩陣相乘展開以后就是幾個數據相乘,因為矩陣因子里面有負數,所以需要
比較大小,把正值給保留下來。
3、求平方和
4、利用altera自帶的IP核,實現開根號處理。
5、跟閾值進行比較
矩陣:
3X3矩陣采用的是altera自帶的ip核,移位ip核taps是指有幾層,如果把data_in算進去的話,taps兩層即可,distance是指距離,每一層的長度是多少,distance
也對應sobel處理的圖片長度,移位ip核運行原理類似與彈珠游戲,新的數據把舊的數據向前推。
時鍾延時:
因為流水線數據處理有延時,所以最終vga顯示使能也需要將移動相應的時鍾來保持同步
/*----------------------------------------------------------------------- Date : 2017-XX-XX Description : Design for sobel. -----------------------------------------------------------------------*/ module sobel ( //global clock input clk , //system clock input rst_n , //sync reset //sobel interface output [10:0] sobel_data , //matrix interface input [ 7:0] matrix_p11 , matrix_p12 , matrix_p13 , input [ 7:0] matrix_p21 , matrix_p22 , matrix_p23 , input [ 7:0] matrix_p31 , matrix_p32 , matrix_p33 , //en input mean_en , output display_val ); //-------------------------------- //Funtion : 變量聲明 reg [9:0] gx_temp1 ; reg [9:0] gx_temp2 ; reg [9:0] gx_data ; reg [9:0] gy_temp1 ; reg [9:0] gy_temp2 ; reg [9:0] gy_data; reg [20:0] gxy_square ; reg [ 4:0] delay_en ; //-------------------------------- //Funtion : 計算Gx Gy always @(posedge clk or negedge rst_n) begin if(!rst_n) begin gx_temp1 <= 1'd0; gx_temp2 <= 1'd0; gx_data <= 1'd0; end else begin gx_temp1 <= matrix_p31 + (matrix_p32 << 1) + matrix_p33; gx_temp2 <= matrix_p11 + (matrix_p12 << 1) + matrix_p13; gx_data <= (gx_temp1 >= gx_temp2) ? gx_temp1 - gx_temp2 : gx_temp2 - gx_temp1; end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin gy_temp1 <= 1'd0; gy_temp2 <= 1'd0; gy_data <= 1'd0; end else begin gy_temp1 <= matrix_p11 + (matrix_p21 << 1) + matrix_p31; gy_temp2 <= matrix_p13 + (matrix_p23 << 1) + matrix_p33; gy_data <= (gy_temp1 >= gy_temp2) ? gy_temp1 - gy_temp2 : gy_temp2 - gy_temp1; end end //-------------------------------- //Funtion : gx^2 + gy^2 always @(posedge clk or negedge rst_n) begin if(!rst_n) gxy_square <= 1'd0; else gxy_square <= gx_data * gx_data + gy_data * gy_data; end //-------------------------------- //Funtion : sqrt sqrt_sobel sqrt_inst( .radical(gxy_square), .q(sobel_data) //remainder ); //-------------------------------- //Funtion : delay_en always @(posedge clk or negedge rst_n) begin if(!rst_n) delay_en <= 1'd0; else delay_en <= {delay_en[3:0] , mean_en}; end assign display_val = delay_en[4]; endmodule