I=imread('1val1.tif');
[m,n]=size(I);I=double(I);
mark(1,1)=I(1,1);mark(1,2)=1;
c=1;S=zeros(m,n);S(1,1)=c;
%c为联通区域的数目;
%用标记法进行区域划分;
%将当前目标依次与左前点、左上点、正上点、右上点比较,如果值相似,作相同标记
%否则标记+1为新的区域。
for i=1:m
for j=1:n
if i==1&j==1;
elseif i==1&j>=2 %对第一行的元素进行区域划分
if abs(I(i,j)-I(i,j-1))<25
S(i,j)=S(i,j-1);
a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
else
c=c+1;S(i,j)=c;a=S(i,j);
mark(a,1)=I(i,j);
mark(a,2)=1;
end
elseif j==1&i>=2 %对第一列的元素进行区域划分
if abs(I(i,j)-I(i-1,j))<25
S(i,j)=S(i-1,j);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j+1))<25
S(i,j)=S(i-1,j+1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
else
c=c+1;S(i,j)=c;a=S(i,j);
mark(a,1)=I(i,j);
mark(a,2)=1;
end
elseif i>1&j==n %对最右边列进行区域划分
if abs(I(i,j)-I(i,j-1))<25
S(i,j)=S(i,j-1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j-1))<25
S(i,j)=S(i-1,j-1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j))<25
S(i,j)=S(i-1,j);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
else
c=c+1;S(i,j)=c;a=S(i,j);
mark(a,1)=I(i,j);
mark(a,2)=1;
end
else % 对中间元素进行区域划分
if abs(I(i,j)-I(i,j-1))<25
S(i,j)=S(i,j-1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j-1))<25
S(i,j)=S(i-1,j-1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j))<25
S(i,j)=S(i-1,j);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
elseif abs(I(i,j)-I(i-1,j+1))<25
S(i,j)=S(i-1,j+1);a=S(i,j);
mark(a,1)=(I(i,j)+mark(a,1)*mark(a,2))/(mark(a,2)+1);
mark(a,2)=mark(a,2)+1;
else
c=c+1;S(i,j)=c;a=S(i,j);
mark(a,1)=I(i,j);
mark(a,2)=1;
end
end
end
end
b=1;error=[0,0];
for i=2:m %寻找本属于同一类但因算法而归为异类的区域
for j=1:n-2
if (abs(I(i,j)-I(i-1,j+2))<25)&(S(i,j)~=S(i-1,j+2))
if find(error(:,1)==S(i,j));
else
error(b,1)=S(i,j);error(b,2)=S(i-1,j+2);
b=b+1;
end
end
end
end
d=1;
for d=1:b-1
a=error(d,1);c=error(d,2);%a为需要纠正的区域的号码,c为目标区域号码
if a~=c
mark(c,1)=(mark(a,1)*mark(a,2)+mark(c,1)*mark(c,2))/(mark(c,2)+mark(a,2));
mark(a,1)=0; %纠正均值
mark(c,2)=mark(c,2)+mark(a,2);mark(a,2)=0; %纠正区域面积
for e=d:b-1 %将已被纠正的区域类别号全被用目标区域的类别号代替
if error(e,2)==a
error(e,2)=c;
end
end
else
end
end
for i=1:m
for j=1:n
if find(error(:,1)==S(i,j))
b=find(error(:,1)==S(i,j));
S(i,j)=error(b,2);
end
end
end
c=size(mark(:,1));
b=1;
for a=1:c %寻找是物体的区域
if mark(a,2)>10
target(b)=a;
b=b+1;
end
end
%对各联通区域用其区域的均值重新赋值;
for i=1:m
for j=1:n
if find(target(:)==S(i,j))
a=S(i,j);
Y(i,j)=mark(a,1);
else
Y(i,j)=0;
end
end
end
y=uint8(Y);
y=im2bw(y);
%y=imfill(y,'holes');
imshow(y);
clear a b c d e i j;