1 背景知識
二值圖像(Binary Image)是指將圖像上的每一個像素只有兩種可能的取值或灰度等級狀態,人們經常用黑白、B&W、單色圖像表示二值圖像。二值圖像是指在圖像中,灰度等級只有兩種,也就是說,圖像中的任何像素不是0就是1,再無其他過渡的灰度值。
二值圖像經常出現在數字圖像處理中作為圖像掩碼或者在圖像分割、二值化和dithering的結果中出現。一些輸入輸出設備,如激光打印機、傳真機、單色計算機顯示器等都可以處理二值圖像。
二值圖像經常使用位圖格式存儲。
二值圖像可以解釋為二維整數格,圖像變形處理領域很大程度上就是受到這個觀點啟發。
膨脹與腐蝕是形態學濾波的兩個基本運算,能實現多種多樣的功能,主要功能如下:
(1)消除噪聲;
(2)分割出獨立的圖像元素;
(3)在圖像中連接相鄰的元素;
(4)尋找圖像中明顯的極大值和極小值區域;
(5)求出圖像的梯度。
圖1 具有斷裂文字的低分辨率樣品文字(見放大的視圖)
如圖1所示,a為具有斷裂文字的低分辨率樣品文字(見放大的視圖),b為結構元,c為圖b對a的膨脹。斷裂線段被連接起來了。
2 膨脹算法
在這里我們演示黑色膨脹過程。
?
圖2 膨脹演示
在二值圖像的膨脹算法過程中我們使用二值圖像3x3圖像矩陣,由圖1可知,當九個格子中只要出現一個‘0’,經過膨脹算法后(x,y)點的值都會是‘0’。
只有(x,y)點以及相鄰的八個點都是‘1’f(x,y)的值才是‘1’。這樣就完成了二值圖像的膨脹。
3 FPGA膨脹算法實現
圖3 二值圖像膨脹FPGA模塊架構
圖3中我們使用串口傳圖傳入的是二值圖像。
FPGA源碼:
? /*
Module name:? binary_image_swell.v
Description:? binary image swell.
?*/
`timescale 1ns/1ps
module binary_image_swell(
? ? ? ?input? ? ? ? ? ? ?clk,? //pixel clk
input? ? ? ? ? ? ?rst_n,
?
input [15:0]? ? ? data_in,
input? ? ? ? ? ? ?data_in_en,
?
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;
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 <= 16'b0;
line0_data1 <= 16'b0;
line0_data2 <= 16'b0;
?
line1_data0 <= 16'b0;
line1_data1 <= 16'b0;
line1_data2 <= 16'b0;
?
line2_data0 <= 16'b0;
line2_data1 <= 16'b0;
line2_data2 <= 16'b0;
?
data_out_en0 <= 1'b0;
data_out_en1 <= 1'b0;
data_out_en2 <= 1'b0;
? end
? else if(data_in_en) begin
? ? line0_data0 <= line0;
line0_data1 <= line0_data0;
line0_data2 <= line0_data1;
?
line1_data0 <= line1;
line1_data1 <= line1_data0;
line1_data2 <= line1_data1;
?
line2_data0 <= line2;
line2_data1 <= line2_data0;
line2_data2 <= line2_data1;
data_out_en0 <= data_in_en;
data_out_en1 <= data_out_en0;
data_out_en2 <= data_out_en1;?
? end
end
always @(posedge clk or negedge rst_n) begin
? if(!rst_n)
? ? data_out <= 16'h0000;
? 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 <= line1_data1;
? ? 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 <= line1_data1;
? ? else?
? ? ? data_out <= 16'h0000;?
end
endmodule?
4實驗結果
圖4 實驗原圖
圖5 實驗原圖顯示結果圖
圖6 膨脹后的結果圖
?
結果分析:
由圖5和圖6來看,明顯線條被加粗,膨脹算法實現。
至此,有興趣的同學可以使用FPGA開發板自己來實驗一下下面這個過程,已達到自我的理解和貫通。
RGB圖像->sobel算子邊緣檢測->二值圖像的腐蝕->二值圖像的膨脹。
評論
查看更多