基於閾值的灰度圖像提取法


  對於簡單的灰度圖像,如果目標與背景的灰度存在一定的差異,那么可以用閾值來提取目標。關鍵是確定閾值,常用方法有:

模態法、P參數法、可變閾值法、大津法和迭代逼近法等。

 

模態法:

  取直方圖的波谷作為閾值。適用於目標與背景灰度差異較大,目標與背景的直方圖各有一個波峰的灰度圖像。

  如果直方圖凹凸較激烈,尋找波谷存在困難,可以用領域點平均化處理使直方圖相對平滑。

 

P參數法:

  當目標占圖像的面積比例已知,且目標最小灰度值大於背景最大灰度值時,可采用P參數法。具體做法是,如果目標灰度接近白色,則在

  直方圖右側開始累計像素,直到累計像素占總像素數比例為P時,將當前的灰度作為閾值(否則從左側開始累計)。

  例如下圖,月亮所占比列為0.45,它最低灰度與背景灰度稍有重合,閾值確定為75,最終基本提取出目標。

        

 

可變閾值法:

  當圖像背景灰度多變時,可以為圖像不同部位設置不同的閾值,這樣可以很好地去除干擾。

  例如提取下圖的蒲公英,圖像上部光照多,主要為蒲公英的羽毛,下部光照少,且主要為莖,對上中下采取不同閾值的提取效果會好很多。

  

          

 

大津法:

  大津法的應用最廣泛,有很好的自適應閾值。適用於批量圖像提取或者動態灰度圖像提取(然而事實證明,當大津遇到反光時,干擾也會很嚴重)。

  大津法的原理如下:

  設T為分割閾值,由此划分出區域記為R1和R2

  R1占圖像總像素的比例為θ1,R2占圖像總像素的比例為θ2

  圖像的平均灰度值為μ0,R1的平均灰度為μ1,R2的平均灰度為μ2

  顯然有:

    μ01122

  如果閾值選得恰當,則R1與R2的灰度差應該較大,那么μ1與μ0、μ2與μ0的差的絕對值也就較大。

  定義類間方差,來反應灰度差大小:

    σ21(μ1022(μ202

  對於每個選定的閾值T,都有σ對應,而最大σ的閾值T則是最佳閾值。

 

  另外,盡管有化簡公式來減少迭代次數的方法(https://www.cnblogs.com/kensporger/p/11270452.html),大津法的過程計算量還是很大的。

 

迭代逼近法:

  此法是大津法的簡化版,具體步驟如下:

  取最大灰度與最小灰度平均值(也可以是圖像平均灰度)為初始閾值T,由此得兩個區域為R1和R2

  計算R1和R2的灰度均值μ1、μ2

  選擇新閾值T=(μ12)/2,重復以上步驟,直到T不再變化或變化在一定范圍內。

  采用該法的效果如圖所示,大概只迭代了五次左右:

  

  但是,該法確定的閾值很粗糙,往往與最佳閾值會有較大偏差,比如提取之前的月亮,表現得就並不是很好了:

  

 

 

以上大部分matlab仿真測試代碼羅列如下:

 

%p參數法確定閾值
function thres  =   pthres(file,p)

    imga = imread(file);
    
    %灰度化
    imga = rgb2gray(imga);
   
    %獲取大小
    [sizex,sizey]=size(imga);
    
    %直方圖
    histogram = zeros(256,1);
    for i=1:sizex
        for j=1:sizey
            histogram(imga(i,j)+1)=histogram(imga(i,j)+1)+1;   
        end
    end
    
    %累計像素
    pixels_cnt=0;
    thres=256;
    while(pixels_cnt<p*sizex*sizey)
        pixels_cnt=pixels_cnt+histogram(thres);
        thres=thres-1;
    end
    
    %根據閾值二值化
    mybw=imbinarize(imga,(thres-1)/255);
    
    subplot(1,2,1);
    imshow(imga);
    title('原圖');
    subplot(1,2,2);
    imshow(mybw);
    title('p參數法二值化');
end

 

 

 

 

%多閾值分割實例
imga=imread('multi_thres.jpg');
imga=rgb2gray(imga);

single  = imbinarize(a,85/255);
multi(250:300,:) = imbinarize(a(250:300,:),85/255);
multi(150:250,:) = imbinarize(a(150:250,:),150/255);
multi(1:150,:) = imbinarize(a(1:150,:),170/255);

subplot(1,3,1);
imshow(imga);
title('原圖');
subplot(1,3,2);
imshow(single);
title('單閾值處理');
subplot(1,3,3);
imshow(multi);
title('多閾值處理');

 

%迭代逼近法
function thres=iterator(file)
    imga = imread(file);
    
    %灰度化
    imga = rgb2gray(imga);
   
    %獲取大小
    [sizex,sizey]=size(imga);
    
    %直方圖與總灰度統計
    gray_sum=0;
    histogram = zeros(256,1);
    for i=1:sizex
        for j=1:sizey
            histogram(imga(i,j)+1)=histogram(imga(i,j)+1)+1; 
            gray_sum= gray_sum+double(imga(i,j)+1);
        end
    end
    %初始閾值
    thres=gray_sum/(sizex*sizey);
    old_thres=0;
    %迭代逼近
    while(abs(thres-old_thres)>1)
       disp(thres);
        u1=0;u2=0;
        cnt1=0;cnt2=0;
        for i=1:thres
            u1=u1+histogram(i)*i;           %統計R1區域平均灰度
            cnt1=cnt1+histogram(i);
        end
        for i=256:-1:thres
            u2=u2+histogram(i)*i;           %統計R2區域平均灰度
            cnt2=cnt2+histogram(i);
        end   

        u1=u1/cnt1;
        u2=u2/cnt2;

        old_thres=thres;
        thres=(u1+u2)/2;                    %新閾值
    end
    
    mybw=imbinarize(imga,(thres-1)/256);

    subplot(1,2,1);
    imshow(imga);
    title('原圖');
    subplot(1,2,2);
    imshow(mybw);
    title('迭代逼近法二值化');    
    
end

 

 

 


免責聲明!

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



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