基於FPGA的二值圖像的邊界提取演算法的實現
基於FPGA的二值圖像的邊界提取演算法的實現
1背景知識
二值圖像(Binary Image)是指將圖像上的每一個像素只有兩種可能的取值或灰度等級狀態,人們經常用黑白、B&W、單色圖像表示二值圖像。二值圖像是指在圖像中,灰度等級只有兩種,也就是說,圖像中的任何像素不是就是1,再無其他過渡的灰度值。
二值圖像的邊界提取主要基於黑白區域的邊界查找。和許多邊界查找演算法相比它適合於二值圖像。
圖1二值圖像邊界提取演示
如圖1所示,圖1 a為一幅簡單的二值圖像,經過邊界提取後形成如圖1 b所示的圖像,顯示出了白色區域的輪廓。
2邊界提取演算法
使用黑色提取,背景為白色,『1』表示白色,『』表示黑色。
圖2二值圖像邊界提取演示
我們使用3x3模板進行邊界提取,所以當3x3九個點都是『1』的時候,輸出為『1』,當九個點都是『』的時候,輸出為『1』,其他情況輸出均為『』。
3 FPGA二值圖像邊界提取演算法實現
圖3二值圖像膨脹FPGA模塊架構
圖3中我們使用串口傳圖傳入的是二值圖像。
FPGA源碼:
/*
Module name: boundary_extraction.v
Description: binary image boundary extraction
*/
`timescale 1ns/1ps
module boundary_extraction(
input clk,//pixel clk
input rst_n,
input hs_in,
input vs_in,
input [15:0] data_in,
input data_in_en,
output hs_out,
output vs_out,
output reg [15:0] data_out,
output data_out_en
);
wire [15:0] line0;
wire [15:0] line1;
wire [15:0] line2;
reg [15:0] line0_data0;
reg [15:0] line0_data1;
reg [15:0] line0_data2;
reg [15:0] line1_data0;
reg [15:0] line1_data1;
reg [15:0] line1_data2;
reg [15:0] line2_data0;
reg [15:0] line2_data1;
reg [15:0] line2_data2;
reg data_out_en0;
reg data_out_en1;
reg data_out_en2;
reg hs_r0;
reg hs_r1;
reg hs_r2;
reg vs_r0;
reg vs_r1;
reg vs_r2;
wire[18:0] result_data;
line3x3 line3x3_inst(
.clken(data_in_en),
.clock(clk),
.shiftin(data_in),
.shiftout(),
.taps0x(line0),
.taps1x(line1),
.taps2x(line2)
);
//------------------------------------------------------------------------------
// Form an image matrix of three multiplied by three
//------------------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
line0_data0
line0_data1
line0_data2
line1_data0
line1_data1
line1_data2
line2_data0
line2_data1
line2_data2
data_out_en0
data_out_en1
data_out_en2
hs_r0
hs_r1
hs_r2
vs_r0
vs_r1
vs_r2
end
else if(data_in_en) begin
line0_data0
line0_data1
line0_data2
line1_data0
line1_data1
line1_data2
line2_data0
line2_data1
line2_data2
data_out_en0
data_out_en1
data_out_en2
hs_r0
hs_r1
hs_r2
vs_r0
vs_r1
vs_r2
end
end
//-------------------------------------------------------------------
// line0_data0 line0_data1 line0_data2
// line1_data0 line1_data1 line1_data2
// line2_data0 line2_data1 line2_data2
//--------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
data_out
else if(data_out_en1)
if((line0_data0 == 16"h0000) && (line0_data1 == 16"h0000) && (line0_data2 == 16"h0000) && (line1_data0 == 16"h0000) && (line1_data1 == 16"h0000) && (line1_data2 == 16"h0000) && (line2_data0 == 16"h0000) && (line2_data1 == 16"h0000) && (line2_data2 == 16"h0000))
data_out
else if((line0_data0 == 16"hffff) && (line0_data1 == 16"hffff) && (line0_data2 == 16"hffff) && (line1_data0 == 16"hffff) && (line1_data1 == 16"hffff) && (line1_data2 == 16"hffff) && (line2_data0 == 16"hffff) && (line2_data1 == 16"hffff) && (line2_data2 == 16"hffff))
data_out
else
data_out
end
endmodule
4實驗結果
圖4實驗原圖1
圖5實驗原圖2
圖6實驗結果圖1
圖7實驗結果圖2
結果分析:圖4和圖6對比,比較粗的線都被查找出了邊緣,只有最細的那條沒有被提取出來,並且被加粗,原因是最細的線條只有三個像素當查找出邊緣後顯示為黑色,兩邊黑色連在一起所以線條就變粗了。圖5和圖7邊緣查找沒有問題。
TAG:FPGA開源工作室 |