当前位置:首页 > > FPGA开源工作室


基于FPGA灰度图像的形态学腐蚀

01

背景知识


数学形态学是一门建立在集论基础上的学科,是几何形态学分析和描述的有力工具。数学形态学的蓬勃发展,其并行快速,易于硬件实现,目前已经在计算机视觉、信号处理与图像分析、模式识别等方面得到了极为广泛的应用。

腐蚀与膨胀是形态学滤波的两个基本运算,通过腐蚀和膨胀两种运算可以实现多种功能,主要如下:

(1) 消除噪声;

(2)分割出独立的图像元素;

(3)在图像中连接相邻的元素;

(4)寻找图像中明显的极大值和极小值区域;

(5)求出图像的梯度。

1 腐蚀膨胀示意图

1 a为大小为448X425像素的灰度级X射线图像;b使用半径为2个像素的圆盘形结构元对图像的腐蚀结果;c用相同的结构元对图像的膨胀结果。原图有Lixi公司提供。

形态学滤波之腐蚀

腐蚀(erode)就是求局部最小值的操作。

从数学角度来看就是将图像f和核(结构元)b进行卷积的一个过程。

b的原点位于(x,y)处时,用一个平坦的结构元b在(x,y)处对图像f的腐蚀,定义为图像f中与b重合区域的最小值,即:

为了方便起见,将腐蚀操作记为:

(x,y)表示当前输入图像的行列坐标;

f(x,y)表示坐标点(x,y)处的图像像素值;

g(x,y)表示坐标点(x,y)处的滤波结果;

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形态学腐蚀效果

03

FPGA实现形态学灰度图像腐蚀



3.1 腐蚀模块的设计

1)比较子模块

2)一维形态学腐蚀子模块

3)二维形态学腐蚀子模块

1) 比较子模块

为了代码更好的移植,我们将比较子模块设计为独立的子模块。

Erode:输出俩个数据的较小值。

(2)一维形态学腐蚀膨胀模块设计

我们要完成对nxn窗口的腐蚀或者膨胀首先我们要做图像行的一维腐蚀或膨胀。例如我们要做3x3窗口的腐蚀或膨胀,一维形态学腐蚀或膨胀如图所示:

(3) 二维形态学腐蚀与膨胀子模块设计


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

形态学腐蚀结果演示

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭