二值化


二值化是圖像處理中最為常見的處理方式,最近做完畢業設計,然后對圖像中二值化處理方式進行整理和分類,主要包括:最大類間方法法(OSTU),迭代閾值法,P分位法,基於最小誤差的全局閾值法,局部閾值法,全局閾值與局部閾值相結合的方法;以下使用matlab編寫的算法。

1、最大類間方差法:

%二值化方法
%OSTU方法:最大類間方差法
function Img = OstuFun(I)
%二值化處理
level = graythresh(I);
Img = im2bw(I,level);

2、迭代閾值法:

%該函數采用迭代法求取閾值
function Out_img = IterateThresh(I)
I = double(I);
%求出圖像的大小
[M,N] = size(I);
%選擇初始閾值T
Z0 = max(max(I));
Z1 = min(min(I));
T = (Z0+Z1)/2;
%新的閾值初始賦值為零
TT = 0;
%預先指定范圍
allow = 5;
d = abs(T-TT);
%計算大於閾值的灰度總值和小於閾值的灰度總值
S0 = 0;N0 = 0;
S1 = 0;N1 = 0;
%閾值迭代
while(d >= allow)
    for i=1:M
        for j=1:N
            if(I(i,j) >= T)
               S0 = S0+I(i,j);
               N0 = N0+1;
            else
                S1 = S1+I(i,j);
                N1 = N1+1;
            end
        end
    end
    %計算新的閾值
    T0 = S0/N0;
    T1 = S1/N1;
    TT = (T0+T1)/2;
    d = abs(T-TT);
    T = TT;
end
%對圖像二值化處理
for i=1:M
    for j=1:N
        if(I(i,j)>=T)
            Out_img(i,j) = 255;
        else
            Out_img(i,j) = 0;
        end
    end
end

3、P分位法

%該函數采用P分位法對圖像進行二值化處理
function Out_img = PFenWei(I)
I1 = double(I);
%獲取圖像的高度和寬度
[M,N] = size(I1);
%對圖像進行分塊處理,對每一塊采用P分位法處理
block = 64;
m = M/block;
n = N/block;
for i = 1:m
    for j = 1:n
        %得到每一小塊圖像矩陣
        temp = I1((i-1)*block+1:i*block,(j-1)*block+1:j*block);
        %求取每小塊的直方圖
        hist = imhist(uint8(real(temp)));
        %求取每一小塊的最佳閾值
        for tt = 1:256
            if(1/block^2 * sum(hist(1:tt)) <= 0.85 && 1/block^2*sum(hist(1:tt+1)) > 0.85 )
                Thresh = tt;
            end
        end
        %對圖像每一小塊二值化處理
        for x = 1:block
            for y = 1:block
                if(temp(x,y) > Thresh)
                    temp(x,y) = 255;
                else
                    temp(x,y) = 0;
                end
            end
        end
        %將取出的每一小塊放入到原始圖像中
        Out_img((i-1)*block+1:i*block,(j-1)*block+1:j*block) = temp;
    end
end
Out_img = uint8(real(Out_img));

4、基於最小誤差的全局閾值法

%圖像二值化方法
%方法:采用最小誤差的閾值分割方法
function out_im = minimumError(im)
out_im=im;
threshold = 0;
%得到圖像中最大像素值
MAX=double(max(im(:)));
%得到圖像的高度和寬度
[M,N]=size(im);
%定義數組,初始化為零
tab(1:MAX+1)=0;
%得到圖像的直方圖
h=imhist(im);
%歸一化直方圖數據
h=h/(M*N);
p=0.0;u=0.0;
%直方圖累加
for i=0:MAX
    p=p+h(i+1);
    u=u+h(i+1)*i;
end


for t=0:MAX
    p1=0.0;u1=0.0;
    k1=0.0;k2=0.0;
    pp1=0.0;pp2=0.0;
    kk1=0.0;kk2=0.0;
    %計算1階統計矩u1,u2
    for i=0:t               
       p1=p1+h(i+1);
       u1=u1+h(i+1)*i;
    end
    if((p-p1)~=0)
       u2=(u-u1)/(p-p1);
    else
       u2=0;
    end
    if(p1~=0)     
        u1=u1/p1;     
    else
        u1=0;
    end
    %計算2階統計矩K1,K2
    for j=0:t                
        k1=k1+(j-u1)*(j-u1)*h(j+1);
    end
    for m=t+1:MAX
        k2=k2+(m-u2)*(m-u2)*h(m+1);
    end
        
    if(p1~=0)       
        k1=sqrt(k1/p1);
        pp1=p1*log(p1);
    end   
    
    if((p-p1)~=0)
        k2=sqrt(k2/(p-p1));
        pp2=(p-p1)*log(p-p1);
    end
    if(k1~=0)
       kk1=p1*log(k1);
    end
    if((k2)~=0)
       kk2=(p-p1)*log(k2);
    end       
    %判別函數
    tab(t+1)=1+2*(kk1+kk2)-2*(pp1+pp2);      
end
%求出最小值
Min=min(tab);
th=find(tab==Min);
temp1 = size(th);
if(temp1(2)==1)
    threshold = th;
else
    threshold = fix(average(th));
end           
for i=1:M
    for j=1:N
        if (out_im(i,j)>threshold)
            out_im(i,j)=255;
        else
            out_im(i,j)=0;
        end
    end
end

5、局部閾值法

%采用局部閾值進行二值化處理
function image = DynamicThresh(I)
%對圖像分塊:64*64,對每塊采用最小誤差求的每塊的灰度值
I2 = blkproc(I,[64 64],'Minmum');
I2 = medfilt2(I2,'symmetric'); 
%還原為1024*1024
rec = imresize(I2,[1024 1024],'bilinear');
%采用動態閾值算法
image = zeros(1024,1024);
for i=1:1024
    for j=1:1024
        if(rec(i,j)>I(i,j))
            image(i,j) = 0;
        else
            image(i,j) = 255;
        end
    end
end

6、全局閾值與局部閾值相結合的方法

%該函數采用全局閾值和局部閾值相結合
function Out_img = MinAndDyThresh(I)
%求取最小誤差法得到的閾值
MinThresh = Minmum(I);
%對圖像分塊:64*64,對每塊采用最小誤差求的每塊的灰度值
blkImg = blkproc(I,[64 64],'Minmum');
I1 = medfilt2(blkImg,'symmetric'); 
%還原為1024*1024,采用雙線性插值法
rec = imresize(I1,[1024 1024],'bilinear');
%動態閾值和極小值誤差相結和
Out_img = zeros(1024,1024);
for i = 1:1024
    for j=1:1024
        temp = 0.7*rec(i,j)+0.3*MinThresh;
        if(I(i,j) > temp)
            Out_img(i,j) = 255;
        else
            Out_img(i,j) = 0;
        end
    end
end

%Minmum函數

function threshold=Minmum(im)         
tt=cputime; 
out_im=im;
MAX=double(max(im(:)));
[M,N]=size(im);
tab(1:MAX+1)=0;
h=imhist(im);
h=h/(M*N);            %歸一化直方圖數據

p=0.0;u=0.0;
for i=0:MAX
    p=p+h(i+1);
    u=u+h(i+1)*i;
end

for t=0:MAX
    p1=0.0;u1=0.0;
    k1=0.0;k2=0.0;
    pp1=0.0;pp2=0.0;
    kk1=0.0;kk2=0.0;
    for i=0:t             %計算1階統計矩u1,u2  
       p1=p1+h(i+1);
       u1=u1+h(i+1)*i;
    end
    if((p-p1)~=0)
       u2=(u-u1)/(p-p1);
    else
       u2=0;
    end
    if(p1~=0)     
        u1=u1/p1;     
    else
        u1=0;
    end

    for j=0:t                %計算2階統計矩K1,K2
        k1=k1+(j-u1)*(j-u1)*h(j+1);
    end
    for m=t+1:MAX
        k2=k2+(m-u2)*(m-u2)*h(m+1);
    end
        
    if(p1~=0)       
        k1=sqrt(k1/p1);
        pp1=p1*log(p1);
    end   
    
    if((p-p1)~=0)
        k2=sqrt(k2/(p-p1));
        pp2=(p-p1)*log(p-p1);
    end
    if(k1~=0)
       kk1=p1*log(k1);
    end
    if((k2)~=0)
       kk2=(p-p1)*log(k2);
    end       
    tab(t+1)=1+2*(kk1+kk2)-2*(pp1+pp2);      %判別函數
end
 
Min=min(tab);
th=find(tab==Min);
temp1 = size(th);
if(temp1(2)==1)
    threshold = th;
else
    threshold = fix(average(th));
end


免責聲明!

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



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