二值化方法研究

 

 

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.

posted @ 2015-08-28 16:36  guopengfei  阅读(3442)  评论(0编辑  收藏  举报