使用积分图像的自适应阈值处理

论文:Adaptive Thresholding Using the Integral Image

地址:https://www.researchgate.net/publication/220494200_Adaptive_Thresholding_using_the_Integral_Image

应用:matlab二值化函数 T = adaptthresh(I)

这应该是adapthresh中的一个方法,但是不是高斯

-----------------------------------------------------------------------------------------

摘要:  图像阈值处理是许多计算机视觉和图形应用中的常见任务。 对图像进行阈值处理的目的是将像素分类为“暗”或“亮”。 自适应阈值处理是一种阈值处理,它考虑了照明的空间变化。 我们提出了一种使用输入的积分图像进行实时自适应阈值处理的技术。 我们的技术是以前方法的扩展。 但是,我们的解决方案对图像中的照明变化更加稳健。 此外,我们的方法简单易行。我们的技术适用于以实时帧速处理实时视频流,使其成为增强现实等交互式应用的有用工具。 

1、简介(introduction)
图像阈值化基于像素的特定特征(例如强度值)来分割数字图像。目标是创建二值图像,将每个像素分类为两个类别之一,例如“暗”或“亮”。这是许多图像处理应用程序和一些计算机图形应用程序中的常见任务。例如,它通常是基于标记的增强现实系统的第一步[Billinghurstet al。 2001;布拉德利和罗斯2004; Fiala 2005],它已被用于高动态范围摄影[Ward2003]。最基本的阈值处理方法是选择固定的阈值并将每个像素与该值进行比较。这些技术已在许多调查论文中进行了广泛的描述和评估[Weszka andRosenfeld 1978; Palumbo等人。 1986; Sahoo等。 1988;李等人。 1990; Glasbey 1993;特里尔和耆那教1995; Sezginand Sankur 2004]。然而,如果照明在图像中在空间上变化或在视频流中超时,则固定阈值经常失败。

为了解释照明的变化,常见的解决方案是自适应阈值处理。主要区别在于为图像中的每个像素计算不同的阈值。该技术为照明变化提供了更强大的功能。存在许多自适应阈值方法[White和Rohrer 1983; Bernsen1986;帕克1991; Wellner 1993;杨等人。 1994; Shen和Ip 1997;陈等人。 1998; Savakis 1998; Sauvolaand Pietikainen 2000;杨和燕2000]。进一步的例子和比较可以在[Venkateswarlu andBoyle 1995; Sezgin和Sankur 2004]。我们使用积分图像提出了一种非常简单明了的技术。我们的方法易于实现实时视频流的实时性能。虽然我们的技术是以前方法的扩展[Wellner 1993],但我们增强了强光照变化的稳健性。此外,我们提供清晰整洁的解决方案,而不会增加实施的复杂性。我们的技术也类似于White和Rohrer用于光学字符识别的阈值处理方法[White and Rohrer 1983],但我们提出了一种针对实时视频设计的实现方法。这项工作的动机是找到真正的现实应用程序。 Pintaric还提出了一种适用于增强现实标记的自适应阈值算法[Pintaric 2003],但是他的方法要求在前一帧中定位一个元素,以便技术正确地进行阈值处理。我们的算法不做任何假设,更通用,适合在任何应用中使用。源代码可在本文末尾列出的地址在线获取。

2、背景 

2.1实时自适应阈值处理
在本文中,我们专注于从实时视频流中自适应地阈值化图像。 为了保持实时性能,阈值算法必须限制通过每个图像的迭代次数。 阈值处理通常是一个子任务,它构成了一个更大的过程的一部分。 例如,在增强现实中,必须对输入图像进行分段以定位场景中用于动态建立相机设置的已知标记。 因此,简单快速的自适应阈值技术是一个重要的工具

2.2积分图像
积分图像(也称为summed-area table)是一种工具,当我们有一个从像素到数值(比如灰度值)的映射函数f(x, y),并且希望计算一个矩形区域内的函数值的和时,积分图是一个非常高效的工具。已应用积分图像的示例包括纹理映射[Crow 1984],图像中的人脸检测[Viola and Jones 2004]和立体对应[Veksler 2003]。在没有积分图像的情况下,我们计算每个矩形窗口中像素点的映射函数的和,需要通过分别计算每个像素的函数值最后叠加实现。但是,如果我们需要计算多个重叠矩形窗口的总和,为了降低时间复杂度和操作次数,我们可以使用积分图像。

为了计算积分图像,我们在每个位置I(x,y)存储左边和上面像素(x,y)的所有f(x,y)项的总和。 对于每个像素,使用以下等式在线性时间内完成(考虑边界情况),

图2(左和中)说明了积分图像的计算。 一旦我们得到积分图像,任何具有左上角(x1,y1)和右下角(x2,y2)的矩形的函数的总和可以使用以下等式计算,计算时间不稳定。

图2(右)说明使用等式2计算矩形D上的f(x,y)之和相当于计算矩形上的和(A + B + C + D) - (A + B) - (A+ C)+ A。

图2:积分图像。 左:图像值的简单输入。 中心:计算的积分图像。 右:使用积分图像计算矩形D的总和。

3、技术

    我们的自适应阈值技术是Wellner方法的简单扩展[WELNER 1993 ]。Welnne算法的主要思想是将每个像素与周围像素的平均值进行比较。特别地,在遍历图像时计算了最后一个像素的近似移动平均值。如果当前像素的值比平均值低百分之t,那么它被设置为黑色,否则它被设置为白色。这种方法的工作是将像素与附近像素的平均值进行比较,从而保持硬对比线,忽略软梯度变化。这种方法的优点是只需要遍历一次图像。WELNER使用1/8倍的图像宽度来表示s的值,t=15。然而,这种方法的一个问题是它依赖于像素的扫描顺序。此外,由于邻域样本在各个方向上不均匀分布,所以在使用平均步长并不是一个很好的表现形式。通过使用积分图像(和骶一个额外的迭代通过图像),我们提出了一个解决方案,不遭受这些问题。我们的技术是干净的,直截了当的,易于编码,并产针对不同的处理方式产生生相同的输出。我们不是计算最后看到的s个像素的平均值,而是计算以每个像素为中心的s x s像素窗口的平均值。 这是比较好的平均值,因为它考虑了所有边上的相邻像素。利用积分图像进行平均计算的时间是线性的。我们在第一次遍历图像的时候计算积分图像在第二遍中,我们利用积分图像计算每个像素的s x s的平均值,使用时间为常量,然后进行比较。如果当前像素的值小于这个平均值,则将其设置为黑色,否则它被设置为白色。下面的伪代码展示了输入图像、输出二值图像、图像宽度W和图像高度H的关系。0

procedure AdaptiveThreshold(in,out,w,h)
    for i=0 to w do
        sum ← 0
        for j=0 to h do
            sum ← sum + in[i,j]
            if i=0 then
                int Img[i,j]←sum
            else
                int Img[i,j]←int Img[i−1,j] + sum
            end if
        end for
    end for 
    for i=0 to w do
        for j=0 to h do
            x1←i−s/2{border checking is not shown}
            x2←i+s/2
            y1←j−s/2
            y2←j+s/2
            count ←(x2−x1)×(y2−y1)
            sum ←intImg[x2,y2]−intImg[x2,y1−1]−intImg[x1−1,y2] + intImg[x1−1,y1−1]
            if (in[i,j]×count)≤(sum ×(100 −t)/100) then
                out[i,j]←0
            else
                out[i,j]←255
            end if
        end for
    end for 


这是我自己根据伪代码写的matlab代码 

I=imread('./pic/2.jpg');
figure
imshow(I)
I=rgb2gray(I);
I=double(I);
sz=size(I);
h=sz(1);
w=sz(2);
in=I;
s=h/8;
t=20;
for i=1:w
    sum =0;
    for j=1:h
        sum=sum + in(j,i);
        if i==1
            intImg(j,i)=sum;
        else
            intImg(j,i)=intImg(j,i-1) + sum;
        end
    end
end
for i=1:w
    for j=1:h
        x1=max(i-round(s/2),2); %{border checking is not shown}
        x2=min(i+round(s/2),w);
        y1=max(j-round(s/2),2);
        y2=min(j+round(s/2),h);
        count =(x2-x1)*(y2-y1);
        sum =intImg(y2,x2)-intImg(y1-1,x2)-intImg(y2,x1-1) + intImg(y1-1,x1-1);
        if (in(j,i)*count)<=(sum *(100 -t)/100) 
            out(j,i)=0;
        else
            out(j,i)=255;
        end
    end
end
figure
imshow(out)

以及测试结果:

原图

s=h/8,t=10

s=h/16,t=10

s=h/8,t=15

s=h/16,t=15

s=h/8,t=20

猜你喜欢

转载自blog.csdn.net/Diana_Z/article/details/81089198