基于FPGA灰度圖像的形態(tài)學腐蝕
掃描二維碼
隨時隨地手機看文章
基于FPGA灰度圖像的形態(tài)學腐蝕
01
背景知識
數(shù)學形態(tài)學是一門建立在集論基礎上的學科,是幾何形態(tài)學分析和描述的有力工具。數(shù)學形態(tài)學的蓬勃發(fā)展,其并行快速,易于硬件實現(xiàn),目前已經(jīng)在計算機視覺、信號處理與圖像分析、模式識別等方面得到了極為廣泛的應用。
腐蝕與膨脹是形態(tài)學濾波的兩個基本運算,通過腐蝕和膨脹兩種運算可以實現(xiàn)多種功能,主要如下:
(1) 消除噪聲;
(2)分割出獨立的圖像元素;
(3)在圖像中連接相鄰的元素;
(4)尋找圖像中明顯的極大值和極小值區(qū)域;
(5)求出圖像的梯度。
圖1 腐蝕膨脹示意圖
圖1 a為大小為448X425像素的灰度級X射線圖像;b使用半徑為2個像素的圓盤形結(jié)構元對圖像的腐蝕結(jié)果;c用相同的結(jié)構元對圖像的膨脹結(jié)果。原圖有Lixi公司提供。
形態(tài)學濾波之腐蝕
腐蝕(erode)就是求局部最小值的操作。
從數(shù)學角度來看就是將圖像f和核(結(jié)構元)b進行卷積的一個過程。
當b的原點位于(x,y)處時,用一個平坦的結(jié)構元b在(x,y)處對圖像f的腐蝕,定義為圖像f中與b重合區(qū)域的最小值,即:
為了方便起見,將腐蝕操作記為:
(x,y)表示當前輸入圖像的行列坐標;
f(x,y)表示坐標點(x,y)處的圖像像素值;
g(x,y)表示坐標點(x,y)處的濾波結(jié)果;
(s,t)表示作用域。
02
Matlab腐蝕源碼
%%image erode
clc
clear all
img_a = imread('flower.bmp');
figure,imshow(img_a);
title('img_a rgb');
img_b = rgb2gray(img_a);
figure,imshow(img_b);
title('img_b gary');
a = [1,1,1;
1,1,1;
1,1,1]; %structural element
b = [1,1,1,1,1;
1,1,1,1,1;
1,1,1,1,1;
1,1,1,1,1;
1,1,1,1,1];
c = [1,1,1,1,1,1,1;
1,1,1,1,1,1,1;
1,1,1,1,1,1,1;
1,1,1,1,1,1,1;
1,1,1,1,1,1,1;
1,1,1,1,1,1,1;
1,1,1,1,1,1,1];
img_c = imerode(img_b,a);
figure,imshow(img_c);
title('img_c 3x3');
img_d = imerode(img_b,b);
figure,imshow(img_d);
title('img_d 5x5');
img_e = imerode(img_b,c);
figure,imshow(img_e);
title('img_e 7x7');
matlab形態(tài)學腐蝕效果
03
FPGA實現(xiàn)形態(tài)學灰度圖像腐蝕
3.1 腐蝕模塊的設計
1)比較子模塊
2)一維形態(tài)學腐蝕子模塊
3)二維形態(tài)學腐蝕子模塊
(1) 比較子模塊
為了代碼更好的移植,我們將比較子模塊設計為獨立的子模塊。
Erode:輸出倆個數(shù)據(jù)的較小值。
(2)一維形態(tài)學腐蝕膨脹模塊設計
我們要完成對nxn窗口的腐蝕或者膨脹首先我們要做圖像行的一維腐蝕或膨脹。例如我們要做3x3窗口的腐蝕或膨脹,一維形態(tài)學腐蝕或膨脹如圖所示:
(3) 二維形態(tài)學腐蝕與膨脹子模塊設計
Erode模塊源碼
/*
Module name: erode.v
Description:
*/
`timescale 1ns/1ps
module erode(
clk,
rst_n,
din,
din_valid,
dout,
dout_valid,
hs_in,
vs_in,
hs_out,
vs_out
);
parameter WIDTH = 8; // data bits is 8
parameter KSZ = 3; // window 3x3
parameter ERO_DIL = 1; //ERO_DIL = 1 erode ;ERO_DIL = 0 dilate.
parameter IMG_WIDTH = 480; //image width 480
input clk;
input rst_n;
input [WIDTH-1:0] din;
input din_valid;
output [WIDTH-1:0] dout;
output dout_valid;
input hs_in;
input vs_in;
output hs_out;
output vs_out;
wire [WIDTH-1:0] morph1d_out;
wire morph1d_data_valid;
wire [WIDTH-1:0] line_out[0:KSZ-1];
wire line_data_valid[0:KSZ-1];
wire [WIDTH-1:0] min[0:KSZ-1];
wire [WIDTH-1:0] max[0:KSZ-1];
//------------------------------------------------------------------------------------
// instantiate a one-dimensional morphology erode or dilate
//------------------------------------------------------------------------------------
morph_1d #(WIDTH,KSZ,ERO_DIL)
morph_1d_inst(
.rst_n(rst_n),
.clk(clk),
.din(din),
.hs_in(hs_in),
.vs_in(vs_in),
.hs_out(hs_out),
.vs_out(vs_out),
.din_valid(din_valid),
.dout_valid(morph1d_data_valid),
.dout(morph1d_out)
);
//------------------------------------------------------
//ERO_DIL == 1 morphology erode
//-------------------------------------------------------
generate
if(ERO_DIL == 1)
begin: xhdl0
assign min[0] = morph1d_out;
assign line_data_valid[0]= morph1d_data_valid;
genvar i;
for(i = 0; i< KSZ -1; i = i + 1)
begin :buf_line1_inst
line_buffer #(WIDTH,IMG_WIDTH,9)
line_buffer_inst(
.rst_n(rst_n),
.clk(clk),
.din(min[i]),
.dout(line_out[i+1]),
.wr_en(line_data_valid[i]),
.data_valid(line_data_valid[i+1])
);
minmax #(WIDTH,1)
minmax_i(
.clk(clk), //pixel clock
.rst_n(rst_n),
.data_valid(line_data_valid[i+1]),
.din(morph1d_out),
.din_r(line_out[i+1]),
.dout_min(min[i+1]),
.dout_max(max[i+1])
);
end
assign dout = min[KSZ-1];
assign dout_valid = line_data_valid[KSZ-1];
end
endgenerate
//-------------------------------------------------------------------
// ERO_DIL == 0 morphology dilate
//------------------------------------------------------------------
generate
if(~(ERO_DIL == 1))
begin: xhdl1
assign max[0] = morph1d_out;
assign line_data_valid[0]= morph1d_data_valid;
genvar i;
for(i = 0; i< KSZ -2; i = i + 1)
begin :buf_line1_inst
line_buffer #(WIDTH,IMG_WIDTH,9)
line_buffer_inst(
.rst_n(rst_n),
.clk(clk),
.din(max[i]),
.dout(line_out[i+1]),
.wr_en(line_data_valid[i]),
.data_valid(line_data_valid[i+1])
);
end
begin :buf_cmp_inst
minmax #(WIDTH,1)
minmax_i(
.clk(clk), //pixel clock
.rst_n(rst_n),
.data_valid(line_data_valid[i+1]),
.din(morph1d_out),
.din_r(line_out[i+1]),
.dout_min(min[i+1]),
.dout_max(max[i+1])
);
end
assign dout = max[i+1];
assign dout_valid = line_data_valid[i+1];
end
endgenerate
endmodule
形態(tài)學腐蝕結(jié)果演示





