文档视界 最新最全的文档下载
当前位置:文档视界 › 设计利用区域生长算法进行图像分割的程序

设计利用区域生长算法进行图像分割的程序

设计利用区域生长算法进行图像分割的程序
设计利用区域生长算法进行图像分割的程序

设计利用区域生长算法进行图像分割的程序

1、目的:把一幅图像划分成满足某种判据的一些区域,在这里形成一个二值图。

2、原理:首先确定每个区域中的某个已知点,加上与已知点相似的邻近点形成一个区域,在这里利用区域的均值。当邻近点与区域均值的差值的绝对值小于阈值T 时,即满足生长条件。方法是从种子点开始,在8连通方向上生长区域,当其邻近点满足生长条件,则就并入小快区域,当新的点被合并后再用新的区域重复这一过程,直到没有可接受的邻近点时该区域生成过程终止。

3、设计思路:

1)通过具体观察某幅图像的直方图,估计其确定种子点范围[S1,S2],并确定其阈值T;

2)透过对整幅图像的扫描,找出某个区域的一个种子点:(.)f x y

3)开始利用8连通方向,以该种子点为中心进行生成区域;[(),()]s r s θ

|(,)(.)|diff f i j f x y T =-<(,)ave f i j =

4)继续用8连通方向,以该区域为中心,把邻近满足生长条件的点并入,生成新的区域; 1(,)k

ave f i j k =∑ |(,)|diff f i j ave T ''=-<

5)重复4)步,直到不再存在邻近满足生长条件的点为止,该区域生成过程结束;

6)继续对图像进行扫描,寻找其他区域的一个种子点,按3)~5)的步骤进行

4、程序设计

根据下面的流程图可分为

区域生长算法实现流程图

5、程序

%district.m主函数

clear

clc

I = imread('bacteria.tif');

subplot(1,2,1)

imshow(I)

title('初始图像');

subplot(1,2,2)

imhist(I)

title('初始图像的直方图');

%透过该直方图确定种子满足S1~S2 的值(灰度值)和判定的依据阈值T

S1=8;S2=70;T=33;

f=double(I);

[m,n]=size(I);

shed1=zeros(3,round(m*n/2)); %存储区域生长方向上的点和该区域的均值的绝对差值和

该%点的坐标

sp1=0; % sp1 相当于指针,指向shed1 中的最后放入的值和坐标

shed2=zeros(2,m); %存储符合生长条件的点的坐标

sp2=0; % sp2 指针,指向shed2 中的最后放入点的坐标

Cut=zeros(size(f)); % Cut 为区域生长后的新图像

Cut=Cut+255; % Cut 矩阵初始值设为255

vb=0; %标记值,当vb=1 时,即要求重新计算已有的栈shed1(1,:) 的大小

for i=1:m

for j=1:n

if (f(i,j)>S1&f(i,j)

已% 有生长区域

Cut(i,j)=0; % 0 时,标记该点在原图像的对应点已并入生长区域

ave=f(i,j); %确定新区域的均值的起始值

k=1; %设置生成的区域的象素个数

[Cut,shed1,sp1,vb]=ruzhan(f,Cut,shed1,sp1,ave,i,j,m,n,vb); %把周围的8 个点

入%栈

[shed1,sp1]=arrange(shed1,sp1); %对栈shed1 的数据进行由大到小的排序

[shed1,sp1,shed2,sp2]=listed(shed1,sp1,T,shed2,sp2); %% 确定符合条件的

生%%长点,将它从shed1 中取出,并放入shed2 中end

% 根据生长点开始用8 连通方式进行生长

while (sp2~=0) %当sp2=0 时表示找不到符合的点,

if (sp2~=0) %当有新的值加入区域时,求新的平均值

sum=ave*k;

for t=1:sp2

x=shed2(1,t); y=shed2(2,t);

sum=sum+f(x,y);

k=k+1;

end

ave=sum/k;

end

for t=1:sp2 %合并栈shed2 中的点,生成新的区域

x=shed2(1,t); y=shed2(2,t);

Cut(x,y)=0;

[Cut,shed1,sp1,vb]=ruzhan(f,Cut,shed1,sp1,ave,x,y,m,n,vb);

end

sp2=0;

[shed1,sp1]=arrange(shed1,sp1);

[shed1,sp1,shed2,sp2]=listed(shed1,sp1,T,shed2,sp2);

end

% 在一片区域生成之后,对栈shed1(1,:)中未并入区域的值进行处理

if (sp1~=0)

for t=1:sp1

x=shed1(2,t); y=shed1(3,t);

Cut(x,y)=255;

end

sp1=0;

shed1=zeros(3,round(m*n/2));

end

end

end

II=uint8(Cut);

figure;

imshow(II);

title('区域生长后的图像(黑色部分)');

%-------------------------------------------------------------

function [shed1,sp1,shed2,sp2]=listed(shed11,sp11,T,shed21,sp21)

% 确定符合条件的生长点,将它从shed1 中取出,并放入shed2 中

shed1=shed11;

sp1=sp11;

shed2=shed21;

sp2=sp21;

while ((sp1~=0)&(shed1(1,sp1)<=T)) %确定shed1 不为空,且存在符合生长条件的点sp2=sp2+1;

shed2(1,sp2)=shed1(2,sp1); shed2(2,sp2)=shed1(3,sp1);

sp1=sp1-1;

end

%-----------------------------------------------------------------

function [shed1,sp1]=arrange(shed11,sp11)

% 排序

shed1=shed11;

sp1=sp11;

% 根据shed1(1,:)的大小,重新排列shed1,按由大到小的顺序

for i=1:sp1-1

maxvalue=shed1(1,i);

x=shed1(2,i);

y=shed1(3,i);

for j=i+1:sp1

if maxvalue

shed1(1,i)=shed1(1,j); shed1(2,i)=shed1(2,j); shed1(3,i)=shed1(3,j);

shed1(1,j)=maxvalue; shed1(2,j)=x; shed1(3,j)=y;

maxvalue=shed1(1,i); x=shed1(2,i); y=shed1(3,i);

end

end

end

%-----------------------------------------------------------------------

function [Cut,shed1,sp1,vb]=ruzhan(f,Cut1,shed11,sp11,ave,i,j,m,n,vb1)

% 入栈

Cut=Cut1;

shed1=shed11;

sp1=sp11;

vb=vb1;

if (vb==1) %重新计算已有的栈shed1(1,:) 的大小

for t=1:sp1

shed1(1,t)=abs(f(shed1(2,t),shed1(3,t))-ave);

end

vb=0;

end

%把新的生长方向上的点存入矩阵zb

for x=i-1:i+1

for y=j-1:j+1

if (x>0&x<=m&y>0&y<=n&Cut(x,y)==255) % 排除已经的生长区域上的点,或

者%已入栈的点,以及防止出界diff=abs(f(x,y)-ave); %该点灰度值和均值的绝对差值

%插入shed1 栈中

sp1=sp1+1; %指向新的入栈点

shed1(1,sp1)=diff;

shed1(2,sp1)=x;

shed1(3,sp1)=y;

Cut(x,y)=125; %标记已入栈的点

end

end

end

6、结果

7、结论

1)基本实现了区域分割的目的;

2)若是种子灰度值和阈值设置妥当,可将一幅图像分成多灰度级的灰度图,同理,也可对

彩色图像进行处理;

3)由于各个图像其特征不同,在种子、阈值上的选取也会有所不同,要根据具体情况而定。4)在这里,种子选取了满足一小段特定灰度值的点,已避免漏过某些模糊区域,(因不含某个灰度值的点而漏过);

5)该算法不足之处是运算量大,占用时间多。

相关文档