当前位置:文档之家› 设计利用区域生长算法进行图像分割的程序

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

设计利用区域生长算法进行图像分割的程序
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)<S2&Cut(i,j)~=0) %确定该点满足作为种子的条件,且未并入
已% 有生长区域
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,j) % 满足条件则交换两列的信息
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)该算法不足之处是运算量大,占用时间多。

相关主题