MATLAB 自己写函数实现查找二值图像连通域,以及对同一个连通域进行贴标签。

  • Post author:
  • Post category:其他




标题MATLAB 自己写函数实现查找二值图像连通域,以及对同一个连通域进行贴标签。

二值图像只有0和1。

四连通就是指一个像素值为1的元素,如果其上下左右任一元素为1,那么这两个元素就属于同一个连通域。

八连通就是指一个像素值为1的元素,如果其上下左右,左上,左下,右上,右下任一元素为1,那么这两个元素就属于同一个连通域。

笔者这里用的是深搜实现的,基本思路就是遍历整个图像,如果找到一个元素为1,那么循着这个元素一直找到他所在的连通域的所有元素为止,代码如下:

四连通

%%%%%%%%%%%%%%%%四联通
f=[0 0 0 1 0 0 0 0;
   0 1 1 1 0 0 0 0;
   0 0 1 1 1 1 0 0;
   0 1 0 1 1 1 1 1;
   0 1 0 1 1 1 0 0;
   0 1 1 0 0 1 0 0;
   0 0 0 0 0 0 0 0;
   0 0 1 0 0 1 0 0;
   1 0 1 1 1 1 1 0;
   1 0 0 1 0 0 0 0;];
[m,n]=size(f);
[m,n]=size(f);
f1=zeros(m+2,n+2);
f1(2:m+1,2:n+1)=f; %f外层添0,不用考虑边界问题 
f
f1;
label=zeros(m+2,n+2); %给f1贴标签
stack=[];
top=0;  %初始栈为空
count=0; %用来贴标签

for i=2:m+1
    for j=2:n+1
        if(f1(i,j)==1&&label(i,j)==0) 
            top=top+1;
            stack(top)=(m+2)*(j-1)+i;  %这里栈记录这个元素的位置,MATLAB的矩阵式按列优先存储的
            count=count+1;
            label(i,j)=count;   %只要有一个满足条件进栈然后进行深度优先搜索,count就+1
        end
        while(top~=0)  %判断栈是否为空,当栈不为空的时候,进行深度搜索
%             if (f1(stack(top)-1)==1&&label(stack(top)-1)==0)||(f1(stack(top)+1)==1&&label(stack(top)+1)==0)||(f1(stack(top)-m-2)==1&&label(stack(top)-m-2)==0)||(f1(stack(top)+m+2)==1&&label(stack(top)+m+2)==0)
                temp=stack(top);  %将要出栈的元素保存
                top=top-1;  %出栈
                if (f1(temp-1)==1&&label(temp-1)==0)
                    top=top+1;
                    stack(top)=temp-1;
                    label(stack(top))=count;
                end
                if (f1(temp+1)==1&&label(temp+1)==0)
                     top=top+1;
                    stack(top)=temp+1;
                    label(stack(top))=count;
                end
                if (f1(temp-m-2)==1&&label(temp-m-2)==0)
                     top=top+1;
                    stack(top)=temp-m-2;
                    label(stack(top))=count;
                end
                if (f1(temp+m+2)==1&&label(temp+m+2)==0)
                     top=top+1;
                    stack(top)=temp+m+2;
                    label(stack(top))=count;
                end
%             end
        end
        
    end
end
label=label(2:m+1,2:n+1)  %贴标签的矩阵

num4=count %连通数

运行结果

八连通

%%%%%%%%%%%%%%%%八联通
f=[0 0 0 1 0 0 0 0;
   0 1 1 1 0 0 0 0;
   0 0 1 1 1 1 0 0;
   0 1 0 1 1 1 1 1;
   0 1 0 1 1 1 0 0;
   0 1 1 0 0 1 0 0;
   0 0 0 0 0 0 0 0;
   0 0 1 0 0 1 0 0;
   1 0 1 1 1 1 1 0;
   1 0 0 1 0 0 0 0;];
[m,n]=size(f);
f1=zeros(m+2,n+2);
f1(2:m+1,2:n+1)=f; %f外层添0,不用考虑边界问题 
f
f1;
label=zeros(m+2,n+2); %给f1贴标签
stack=[];
top=0;  %初始栈为空
count=0; %用来贴标签

for i=2:m+1
    for j=2:n+1
        if(f1(i,j)==1&&label(i,j)==0)
            top=top+1;
            stack(top)=(m+2)*(j-1)+i;  %这里栈记录这个元素的位置,MATLAB的矩阵式按列优先存储的
            count=count+1;
            label(i,j)=count;   %只要有一个满足条件进栈然后进行深度优先搜索,count就+1
        end
        while(top~=0)  %判断栈是否为空,当栈不为空的时候,进行深度搜索
%             if (f1(stack(top)-1)==1&&label(stack(top)-1)==0)||(f1(stack(top)+1)==1&&label(stack(top)+1)==0)||(f1(stack(top)-m-2)==1&&label(stack(top)-m-2)==0)||(f1(stack(top)+m+2)==1&&label(stack(top)+m+2)==0)
                temp=stack(top);  %将要出栈的元素保存
                top=top-1;  %出栈
                if (f1(temp-1)==1&&label(temp-1)==0)
                    top=top+1;
                    stack(top)=temp-1;
                    label(stack(top))=count;
                end
                if (f1(temp+1)==1&&label(temp+1)==0)
                     top=top+1;
                    stack(top)=temp+1;
                    label(stack(top))=count;
                end
                if (f1(temp-m-2)==1&&label(temp-m-2)==0)
                     top=top+1;
                    stack(top)=temp-m-2;
                    label(stack(top))=count;
                end
                if (f1(temp-m-2-1)==1&&label(temp-m-2-1)==0)
                     top=top+1;
                    stack(top)=temp-m-2-1;
                    label(stack(top))=count;
                end
                 if (f1(temp-m-2+1)==1&&label(temp-m-2+1)==0)
                     top=top+1;
                    stack(top)=temp-m-2+1;
                    label(stack(top))=count;
                end
                if (f1(temp+m+2)==1&&label(temp+m+2)==0)
                     top=top+1;
                    stack(top)=temp+m+2;
                    label(stack(top))=count;
                end
                 if (f1(temp+m+2-1)==1&&label(temp+m+2-1)==0)
                     top=top+1;
                    stack(top)=temp+m+2-1;
                    label(stack(top))=count;
                 end
                 if (f1(temp+m+2+1)==1&&label(temp+m+2+1)==0)
                     top=top+1;
                    stack(top)=temp+m+2+1;
                    label(stack(top))=count;
                end
%             end
        end
        
    end
end
label=label(2:m+1,2:n+1) %贴标签的矩阵

num8=count  %连通数

运行结果

有问题欢迎指出

笔者也在学习当中,记录下自己的学习过程,转载请注明出处



版权声明:本文为JMasker原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。