ITKeyword,专注技术干货聚合推荐

注册 | 登录

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

ymqq1 分享于 2013-04-08

推荐:Matlab函数bwlabel:在二值图像中标记连通区域

用法: L = bwlabel(BW,n) 返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,

2020腾讯云8月秒杀活动,优惠非常大!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1040

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

        今天在论坛上,问了一个问题如下(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 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)在每个像素点的级别上   

推荐:图论--Matlab实现最短路径算法

       使用Matlab的graphshortestpath 函数,快速求得最短路径,详情请参照Matlab帮助文档。 graphshortestpath solves the shortest path problem in graph.  

           我参照博文《多值连通区域标记算法》(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;
    end
end
for 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
    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连通修改也比较简单。




推荐:KNN的matlab实现算法(转载)

    讨厌死matlab了,呵呵其实是不经常用导致简单的语法结构都忘了每次都要查来查去的。我今天差点就想改下我以前c++的那个算了,后来想这样可不好,不能因为

        今天在论坛上,问了一个问题如下(http://bbs.csdn.net/topics/390418066):   请问多值连通区域应该如何标记?用bwlabel只能求二值的连通区域标记。a=[1 1 1 1 1 1 1 1 1 1 1 1 1

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。