常见的二值化方法

二值化是图像处理中最为常见的处理方式,最近做完毕业设计,然后对图像中二值化处理方式进行整理和分类,主要包括:最大类间方法法(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

你可能感兴趣的:(Matlab图像处理)