腐蝕膨脹-算法


本篇文章要分享的是基於MATLAB的腐蝕膨脹算法實現,腐蝕膨脹是形態學圖像處理的基礎,腐蝕在二值圖像的基礎上做“收縮”或“細化”操作,膨脹在二值圖像的基礎上做“加長”或“變粗”的操作。

什么是二值圖像呢?把一幅圖片看做成一個二維的數組,那么二值圖像是一個只有0和1的邏輯數組,我們前面Sobel邊緣檢測后的圖像輸出邊緣效果,設置個閾值,大於閾值輸出為1,小於閾值輸出為0,最后輸出就是一幅二值圖像了。

腐蝕

腐蝕是一種消除邊界點,使邊界向內部收縮的過程。可以用來消除小且無意義的物體。用3X3的結構元素,掃描圖像的每一個像素,用結構元素與其覆蓋的二值圖像做“與”操作,如果都為1,結果圖像的該像素為1。否則為0。結果會使二值圖像小一圈。

有一個形象的比喻來可以說明該運算,用0表示蛀蟲,1表示大米。蛀蟲腐蝕大米的過程便是

 

 

 

腐蝕

如圖所示,對於一個像素矩陣而言,只要有蛀蟲(0)的存在,大米(1)就會被腐蝕掉了,即使只存在一個蛀蟲(0),但是還是會被蛀蟲腐蝕完畢,最后一幅圖上面由於沒有蛀蟲(0)所以大米完好無損。

關於算法的實現,可以用下式子來表示,即3x3像素的運算:

P = P11 & P12 & P13 & P21 & P22 & P23 & P31 & P32 & P33

在FPGA中,為了通過面積去換速度,我們將上式改變如下:                       

P1 = P11 & P12 & P13

P2 = P21 & P22 & P23

P3 = P31 & P32 & P33

P = P1 & P2 & P3

MATLAB中可以直接寫一個按位或運算。

膨脹

膨脹是將與物體接觸的所有背景點合並到該物體中,使邊界向外部擴張的過程。可以用來填補物體中的空洞。用3X3的結構元素,掃描圖像的每一個像素,用結構元素與其覆蓋的二值圖像做“與”操作,如果都為0,結果圖像的該像素為0,。否則為1。結果使二值圖像擴大一圈。

先腐蝕后膨脹的過程稱為開運算。用來消除小物體、在纖細點處分離物體、平滑較大物體的邊界的同時並不明顯的改變其面積。先膨脹后腐蝕的過程稱為比運算,用來填充物體內細小空間、連接鄰近物體、平滑其邊界的同時並不明顯改變其面積。

膨脹算法用最簡單的比喻來描述:0表示害蟲,1表示青蛙,青蛙吃了害蟲表示膨脹運算,我們用3*3像素陣列來解釋:

 

 

 

膨脹

如圖所示,圖左只有害蟲(0),所以害蟲都活着,中間那個圖,雖然只有一個害蟲,但是還是會被青蛙全部吃掉,最右邊的那幅圖,都是青蛙,所以青蛙始終是青蛙。

關於算法的實現,可以用下式子來表示,即3x3像素的運算:

P = P11 | P12 | P13 | P21 | P22 | P23 | P31 | P32 | P33

在HDL中,為了通過面積去換速度,我們將上式改變如下:                             

P1 = P11 | P12 | P13

P2 = P21 | P22 | P23

P3 = P31 | P32 | P33

P = P1 | P2 | P3

MATLAB中可以直接寫一個按位與運算。

開運算閉運算

先腐蝕后膨脹叫開運算,開運算的作用是清除圖像邊緣周圍非邊緣的細小的點。先膨脹后腐蝕為閉運算,閉運算的作用是清除圖像內部的空洞,

如果我們的目標物體外面有很多無關的小區域,就用開運算去除掉;如果物體內部有很多小黑洞,就用閉運算填充掉。

MATLAB邏輯運算函數

bitand(), 對十進制數進行逐位邏輯與運算:先將十進制數轉換成二進制數,然后逐位與運算,其運算結果轉換為十進制。

bitor(), 對十進制數進行逐位邏輯或運算:先將十進制數轉換成二進制數,然后逐位與運算,其運算結果轉換為十進制。

MATLAB代碼實現

%%%imopen Erosion_Dilation 
clc,clear,close all,clear all

img = imread('1.png');
img_gray = rgb2gray(img);
 figure;
subplot(2,2,1),imshow(img),title('灰度圖像') 
subplot(2,2,2),imshow(img_gray),title('灰度圖像')
hold on;
%%中值濾波
 %Median Filter 
 imgn = imnoise(img_gray,'salt & pepper',0.02); 
 subplot(2,2,3),imshow(imgn),title('椒鹽噪聲圖像'); 

 Median_Img = img_gray; 
 [ROW,COL] = size(Median_Img);
 for r = 2:ROW-1 
     for c = 2:COL-1 
         median3x3 =[imgn(r-1,c-1)    imgn(r-1,c) imgn(r-1,c+1) 
                     imgn(r,c-1)      imgn(r,c)      imgn(r,c+1) 
                     imgn(r+1,c-1)      imgn(r+1,c) imgn(r+1,c+1)]; 
         sort1 = sort(median3x3, 2, 'descend');
         sort2 = sort([sort1(1), sort1(4), sort1(7)], 'descend'); 
         sort3 = sort([sort1(2), sort1(5), sort1(8)], 'descend'); 
         sort4 = sort([sort1(3), sort1(6), sort1(9)], 'descend'); 
         mid_num = sort([sort2(3), sort3(2), sort4(1)], 'descend'); 
         Median_Img(r,c) = mid_num(2); 
     end 
 end 
  
subplot(2,2,4),imshow(Median_Img),title('中值濾波圖像')

%%Sobel算子邊緣檢測
 Median_Img = double(Median_Img);
 Sobel_Img = zeros(ROW,COL);
 Sobel_Threshold = 80;
for r = 2:ROW-1
     for c = 2:COL-1
        Sobel_x = Median_Img(r-1,c+1) + 2*Median_Img(r,c+1) + Median_Img(r+1,c+1) - Median_Img(r-1,c-1) - 2*Median_Img(r,c-1) - Median_Img(r+1,c-1);
        Sobel_y = Median_Img(r-1,c-1) + 2*Median_Img(r-1,c) + Median_Img(r-1,c+1) - Median_Img(r+1,c-1) - 2*Median_Img(r+1,c) - Median_Img(r+1,c+1);
        %Sobel_Num = abs(Sobel_x) + abs(Sobel_y);
         Sobel_Num = sqrt(Sobel_x^2 + Sobel_y^2);
        if(Sobel_Num > Sobel_Threshold)
             Sobel_Img(r,c)=1;
         else
             Sobel_Img(r,c)=0;
         end
     end
end
figure
subplot(2,2,1),imshow(Sobel_Img),title('Sobel算子圖像')
BW1=edge(img_gray,'sobel'); %用Sobel算子進行邊緣檢測
subplot(2,2,2),imshow(BW1),title('Sobel算子圖像')

%%腐蝕算法
Erosion_img = zeros(ROW,COL); 
for r = 2:ROW-1
     for c = 2:COL-1
        %and1 = bitand(Sobel_Img(r-1,c-1) + bitand(Sobel_Img(r-1,c) + Sobel_Img(r-1,c+1)));
        %and2 = bitand(Sobel_Img(r  ,c-1) + bitand(Sobel_Img(r  ,c) + Sobel_Img(r  ,c+1)));
        %and3 = bitand(Sobel_Img(r+1,c-1) + bitand(Sobel_Img(r+1,c) + Sobel_Img(r+1,c+1)));
        %Erosion_img(r,c) = bitand(and1,bitand(and2,and3));
        and1 = Sobel_Img(r-1,c-1) & Sobel_Img(r-1,c) & Sobel_Img(r-1,c+1);
        and2 = Sobel_Img(r  ,c-1) & Sobel_Img(r  ,c) & Sobel_Img(r  ,c+1);
        and3 = Sobel_Img(r+1,c-1) & Sobel_Img(r+1,c) & Sobel_Img(r+1,c+1);
        Erosion_img(r,c) = and1 & and2 & and3;
     end
end
subplot(2,2,3),imshow(Erosion_img),title('腐蝕圖像')
%%膨脹算法
Dilation_img = zeros(ROW,COL); 
for r = 2:ROW-1
     for c = 2:COL-1
        %and1 = bitand(Sobel_Img(r-1,c-1) + bitand(Sobel_Img(r-1,c) + Sobel_Img(r-1,c+1)));
        %and2 = bitand(Sobel_Img(r  ,c-1) + bitand(Sobel_Img(r  ,c) + Sobel_Img(r  ,c+1)));
        %and3 = bitand(Sobel_Img(r+1,c-1) + bitand(Sobel_Img(r+1,c) + Sobel_Img(r+1,c+1)));
        %Erosion_img(r,c) = bitand(and1,bitand(and2,and3));
        and1 = Sobel_Img(r-1,c-1) | Sobel_Img(r-1,c) | Sobel_Img(r-1,c+1);
        and2 = Sobel_Img(r  ,c-1) | Sobel_Img(r  ,c) | Sobel_Img(r  ,c+1);
        and3 = Sobel_Img(r+1,c-1) | Sobel_Img(r+1,c) | Sobel_Img(r+1,c+1);
        Dilation_img(r,c) = and1 | and2 | and3;
     end
end
subplot(2,2,4),imshow(Dilation_img),title('膨脹圖像')

%%開運算-先腐蝕后膨脹算法
Erosion_Dilation_img = zeros(ROW,COL); 
for r = 2:ROW-1
     for c = 2:COL-1
        %and1 = bitand(Sobel_Img(r-1,c-1) + bitand(Sobel_Img(r-1,c) + Sobel_Img(r-1,c+1)));
        %and2 = bitand(Sobel_Img(r  ,c-1) + bitand(Sobel_Img(r  ,c) + Sobel_Img(r  ,c+1)));
        %and3 = bitand(Sobel_Img(r+1,c-1) + bitand(Sobel_Img(r+1,c) + Sobel_Img(r+1,c+1)));
        %Erosion_img(r,c) = bitand(and1,bitand(and2,and3));
        and1 = Erosion_img(r-1,c-1) | Erosion_img(r-1,c) | Erosion_img(r-1,c+1);
        and2 = Erosion_img(r  ,c-1) | Erosion_img(r  ,c) | Erosion_img(r  ,c+1);
        and3 = Erosion_img(r+1,c-1) | Erosion_img(r+1,c) | Erosion_img(r+1,c+1);
        Erosion_Dilation_img(r,c) = and1 | and2 | and3;
     end
end
figure
subplot(1,2,1),imshow(Erosion_Dilation_img),title('先腐蝕在膨脹圖像')
%%閉運算-先膨脹后腐蝕算法
Dilation_Erosion_img = zeros(ROW,COL); 
for r = 2:ROW-1
     for c = 2:COL-1
        %and1 = bitand(Sobel_Img(r-1,c-1) + bitand(Sobel_Img(r-1,c) + Sobel_Img(r-1,c+1)));
        %and2 = bitand(Sobel_Img(r  ,c-1) + bitand(Sobel_Img(r  ,c) + Sobel_Img(r  ,c+1)));
        %and3 = bitand(Sobel_Img(r+1,c-1) + bitand(Sobel_Img(r+1,c) + Sobel_Img(r+1,c+1)));
        %Erosion_img(r,c) = bitand(and1,bitand(and2,and3));
        and1 = Dilation_img(r-1,c-1) & Dilation_img(r-1,c) & Dilation_img(r-1,c+1);
        and2 = Dilation_img(r  ,c-1) & Dilation_img(r  ,c) & Dilation_img(r  ,c+1);
        and3 = Dilation_img(r+1,c-1) & Dilation_img(r+1,c) & Dilation_img(r+1,c+1);
        Dilation_Erosion_img(r,c) = and1 & and2 & and3;
     end
end
subplot(1,2,2),imshow(Dilation_Erosion_img),title('先膨脹在腐蝕圖像')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM