• 二值化方法研究


     

     

    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.

  • 相关阅读:
    8.09_python_lx_shopping
    8.06_python_lx_day25
    8.05_python_lx_day24
    8.05_python_lx_day23
    8.03_python_lx_day21<2>
    Java注解
    Java多线程04
    Java多线程03
    Java多线程02
    Java多线程01
  • 原文地址:https://www.cnblogs.com/guopengfei/p/4766912.html
Copyright © 2020-2023  润新知