请问多值连通区域应该如何标记?用bwlabel只能求二值的连通区域标记。
a=
[
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 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 4 4 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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
]
我想把这样的矩阵做连通区域标记,应该如何进行?
要注意的是,其中有一片被2包围的1要和其他的1标记不同。
按照一般来说可以使用bwlable来实现,如下
%I必须事先二值化
[L, num] = bwlabel(I,8);
MyRG=label2rgb(L); 这样也许会有背景的问题,比如
I=
[
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
] I的处理结果,就是
[
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
]
其关键在于,bwlable存在一个背景色的缘故,它把背景色当做一个整体,并不分拆。这样对于有一些场合就显得不合适了,针对这种问题的处理方法:
(1)在每个像素点的级别上
I=[
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 2 2 2 2 2 2 2 1 1 1 1 1
1 1 2 1 1 1 1 1 1 2 1 1 3 1 1
1 1 2 1 1 1 1 1 1 2 1 1 3 1 1
1 1 2 1 1 1 1 1 1 2 1 1 3 1 1
1 1 2 2 2 2 2 2 2 2 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
];
[m,n]=size(I);
for i=1:m
for j=1:n
root(i,j)=(i-1)*n+j;
end
end
for i=1:m
for j=1:n
if(i>1&&j
if(I(i-1,j+1)==I(i,j)) root(i,j)=root(i-1,j+1);
end
end
if(j
if(I(i,j+1)==I(i,j)) root(i,j+1)=root(i,j);
end
end
if(i
if(I(i+1,j)==I(i,j)) root(i+1,j)=root(i,j);
end
end
if(i
if(I(i+1,j+1)==I(i,j)) root(i+1,j+1)=root(i,j);
end
end
end
end
(2)针对相同像素集合的级别上
% a = [
% 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 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 4 4 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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% ];
a = [ 1 2 2 2 3
1 2 1 2 1
1 2 2 2 1
1 4 1 1 1
1 1 1 1 1];
maxa = max(a(:));
mina = max(min(a(:)),1);
result = zeros(size(a));
curnum = 0;
for i = mina : maxa
curImg = bwlabel(a==i);
for j = 1 : max(curImg(:))
curImg(curImg==j) = curnum+j;
end
curnum = curnum+length(unique(curImg))-1;
result = result+curImg;
end
result
(3)针对图像的特点
%以下代码貌似还有问题,我再改正一下
% 也可以这样,供参考
I=[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 2 2 2 2 2 2 2 1 1 1 1 1
1 1 2 1 1 1 1 1 1 2 3 3 3 1 1
1 1 2 1 1 1 1 1 1 2 3 1 3 1 1
1 1 2 1 1 1 1 1 1 2 3 3 3 1 1
1 1 2 2 2 2 2 2 2 2 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];
f=imfill(I,'holes');
holes=f-I;
l=bwlabel(holes)*(max(I(:)));
r=I+l
PS:1、今天有点事,晚些时候再把注释加上去。
2、以上代码是8连通,如果想4连通修改也比较简单。