标题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 版权协议,转载请附上原文出处链接和本声明。