多值连通区域标记算法的matlab实现

来源:互联网 发布:淘宝拒绝退款怎么办 编辑:程序博客网 时间:2024/04/30 15:51

        今天在论坛上,问了一个问题如下(http://bbs.csdn.net/topics/390418066):

 

请问多值连通区域应该如何标记?用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 11 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 11 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 11 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 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)在每个像素点的级别上   

           我参照博文《多值连通区域标记算法》(http://blog.csdn.net/ymqq1/article/details/8773484),写了一个matlab的多值连通区域标记算法,其算法思想很简单,就是并查集。

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;    endendfor i=1:m    for j=1:n         if(i>1&&j<n)             if(I(i-1,j+1)==I(i,j)) root(i,j)=root(i-1,j+1);             end         end         if(j<n)             if(I(i,j+1)==I(i,j)) root(i,j+1)=root(i,j);             end         end         if(i<m)             if(I(i+1,j)==I(i,j)) root(i+1,j)=root(i,j);             end         end         if(i<m&&j<n)             if(I(i+1,j+1)==I(i,j))  root(i+1,j+1)=root(i,j);             end         end    endend

(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;endresult

(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连通修改也比较简单。




原创粉丝点击