二值化方法研究


 

 

1 otsu方法參考我的另一篇博文: OTSU算法學習 OTSU公式證明

2 sauvola方法, 參考我的另一篇博文: sauvola二值化算法研究

3 Bersen方法

 

Bersen方法感覺有些粗糙, 只是考慮目標點附近區域的像素灰度值的最大值和最小值, 閾值是最大值和最小值的均值.下面是它的matlab實現,出自這篇博文【二值化】Bernsen算法.如果用C語言實現要用積分圖的方法.

%局部閾值操作Bersen算法

clc

clear

 

I = imread('card8.bmp');

 

w =1;%矩陣大小為2*w+1

T =0;%閾值大小

max =0;

min =0;

[m,n]= size(I);

T = zeros(m -2*w,n -2*w);

 

%根據bersen算法計算每個像素點的閾值

for i =(w +1):(m - w)

    for j =(w +1):(n - w)

        max = uint8(I(i,j));

        min = uint8(I(i,j));

        for k =-w:w

            for l =-w:w

                if max < uint8(I(i + k,j + l))

                    max = uint8(I(i + k,j + l));

                end

                if min > uint8(I(i + k,j + l))

                    min = uint8(I(i + k,j + l));

                end

            end

        end

        T(i,j)=0.5*(max + min);

    end

end

for i =(w +1):(m - w)

    for j =(w +1):(n - w)

        if I(i,j)> T(i,j)

            I(i,j)= uint8(255);

        else

            I(i,j)= uint8(0);

        end

    end

end

imshow(I);

 

下圖是這個方法的效果

clip_image001[4]clip_image002[4]

上圖中對於圖像右側的效果很差.

4 niblack算法

Niblack二值化算法是比較簡單的局部閾值方法,閾值的計算公式是T = m + k*v,其中m為以該像素點為中心的區域的平均灰度值,v是該區域的標准差,k是一個系數. sauvola二值化算法的計算公式是T = mean*(1 + k*((std / 128) - 1)). Niblacksauvola方法類似.下面貼matlab實現的代碼和效果圖.不做進一步分析了.

I = imread('2.bmp');

%I = rgb2gray(I);

 

w =  2;%  

max =0;  

min =0;  

[m,n]= size(I);  

T = zeros(m ,n );  

 

%

for i =(w +1):(m - w)  

    for j =(w +1):(n - w)     

        sum =0;

        for k =-w:w  

            for l =-w:w  

                sum = sum + uint32(I(i + k,j + l));

            end  

        end  

        average = double(sum)/((2*w+1)*(2*w+1));

        s =0;

        for k =-w:w  

            for l =-w:w  

                s = s +   (uint32(I(i + k,j + l))- average)*(uint32(I(i + k,j + l))- average);

            end  

        end  

        s= sqrt(double(s)/((2*w+1)*(2*w+1)));

       

        T(i,j)= average +0.2*s;

    end  

end  

for i =  1:m

    for j =1:n

        if I(i,j)> T(i,j)  

            I(i,j)= uint8(255);  

        else 

            I(i,j)= uint8(0);  

        end  

    end  

end  

imshow(I); 

 

 

clip_image003[4]

5 循環閾值算法

      代碼的實現和k均值聚類算法類似,但是累積值在循環中沒有清空,具體原因不知道.只是把代碼貼和效果到下面.

clc

clear

I = imread('2.bmp');

%I = rgb2gray(G);

%l = rgb2gray(h);%轉換成灰度圖像,得到灰度值

%imhist(img);%得到灰度直方圖

%disp(img);%顯示各像素的灰度值

 

%循環閾值選擇方法

gray1 =0;%一部分圖像的灰度值之和

gray2 =0;%另一部分圖像的灰度值之和

u1 =0;%一部分圖像的平均灰度值

u2 =0;%另一部分的平均灰度值

k =0;%一部分圖像的像素個數

r =0;%另一部分圖像的像素個數

x =0;%閾值和

T =0;%圖像的閾值

[m,n]= size(I)%獲取圖像大小

 

%獲取平均閾值

for i =1:m

    for j =1:n

        x = x + uint32(I(i,j));

    end

end

T = x/(m*n);%初始閾值

 

T1 =0;

while T ~= T1

    T1 = T;

    for i =1:m

        for j =1:n

            if I(i,j)< T

                gray1 = gray1 + uint32(I(i,j));

                k = k +1;

            else

                gray2 = gray2 + uint32(I(i,j));

                r = r +1;

            end

        end

    end

    u1 = gray1/k;

    u2 = gray2/r;   

    T =(u1 + u2)/2;%新的閾值

end

%BW = im2bw(g,T);%轉換成二值圖像

T %輸出最后選擇的閾值

%顯示區域,把不在閾值范圍內的點的灰度值置為255

for i =1:m

    for j =1:n

        if I(i,j)> T

            I(i,j)= uint32(255);

        else

            I(i,j)= uint32(0);

        end

    end

end

%se = strel('disk',1);

%h = imclose(I,se);

%h = imdilate(I,se);

%y = imerode(h,se);

 

%h = medfilt2(I,[3,3];

%imshow(y);

imshow(I);

 

 

clip_image004[4]

 

總結: 實際應用中實現上首先要用積分圖技術來實現提速,其次要綜合考慮全局閾值方法和局部閾值方法,以全局閾值為基礎,考慮局部均值,二值化等.這個局部不能太小,太小了就會有噪點.

本文參考了博文圖像二值化算法總結,這里感謝cxf7394373.


免責聲明!

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



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