MATLAB 自己寫函數實現查找二值圖像連通域,以及對同一個連通域進行貼標籤。

標題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  %連通數

運行結果

有問題歡迎指出
筆者也在學習當中,記錄下自己的學習過程,轉載請註明出處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章