为什么索贝尔算子看起来那样?

时间:2013-06-13 02:07:49

标签: image-processing computer-vision edge-detection

对于图像导数计算,Sobel算子看起来像这样:

[-1 0 1]
[-2 0 2]
[-1 0 1]

我不太了解有关它的两件事,

1.为什么中心像素 0 ?我不能只使用下面的运算符,

[-1 1]
[-1 1]
[-1 1]

2.为什么中心行是其他行的2倍?

我搜索了我的问题,没有找到任何可以说服我的答案。请帮帮我。

3 个答案:

答案 0 :(得分:53)

在计算机视觉中,通常没有完美的,通用的做事方式。大多数情况下,我们只是尝试操作员,查看其结果并检查它们是否符合我们的需求。对于梯度计算也是如此:Sobel算子是计算图像梯度的众多方法之一,已经证明它在许多用例中都很有用。

事实上,我们能想到的更简单的梯度算子比你上面建议的更简单:

[-1 1]

尽管它很简单,但这个算子还有第一个问题:当你使用它时,你计算两个位置之间的梯度而不是一个位置。如果您将其应用于2像素(x,y)(x+1,y),您是否计算了位置(x,y)(x+1,y)的渐变?实际上,你计算的是位置(x+0.5,y)的渐变,使用半像素并不是很方便。这就是我们在中间加零的原因:

[-1 0 1]

将此一个应用于像素(x-1,y)(x,y)(x+1,y)会清楚地为您提供中心像素(x,y)的渐变。

这个也可以被视为两个[-1 1]滤镜的卷积:[-1 1 0],用于计算像素左侧(x-0.5,y)位置的渐变,[0 -1 1]计算像素右侧的渐变。

现在这个过滤器还有另一个缺点:它对噪音非常敏感。这就是为什么我们决定不将它应用于单行像素,而是应用于3行:这样可以在这3行上获得平均梯度,从而减弱可能的噪声:

[-1 0 1]
[-1 0 1]
[-1 0 1]

但是这个过程往往会使事情变得有点过分:当应用于一个特定的行时,我们会失去很多因为这个特定行的细节。为了解决这个问题,我们希望对中心行给予更多的权重,这将允许我们通过考虑前一行和下一行中发生的事情来消除可能的噪声,但仍然保持该行的特异性。这就是Sobel滤波器的原因:

[-1 0 1]
[-2 0 2]
[-1 0 1]

篡改系数可以导致其他梯度算子,例如Scharr算子,它给中心行提供了更多的权重:

[-3  0 3 ]
[-10 0 10]
[-3  0 3 ]

这也有数学上的原因,比如这些过滤器的可分性 ......但我更喜欢把它看作是一个实验性的发现,它被证明具有有趣的数学性质,因为实验在我的计算机视觉的核心意见。 只要符合您的需求,只有您的想象力才能创造出新的想象力......

答案 1 :(得分:18)

  

编辑 Sobel运营商看起来如此的真正原因可能是   通过阅读an interesting article by Sobel himself找到。我的   快速阅读本文表明索贝尔的想法是获得一个   通过平均水平来改进梯度估计,   垂直和对角线的中心差异。现在当你打破了   渐变成垂直和水平分量,对角线中央   差异包括在两者中,而纵向和横向   中心差异仅包含在一个中。两个避免加倍   因此,计算对角线的重量应该是一半   垂直和水平。 1和2的实际权重是正确的   方便定点运算(实际上包括一个比例   因子16)。

我主要赞同@mbrenon,但在评论中有几点难以理解。

首先在计算机视觉中,“最常见的是,我们只是尝试操作员”方法只是浪费时间并且与可能实现的结果相比给出差的结果。 (也就是说,我也喜欢尝试。)

确实,使用[-1 0 1]的一个很好的理由是它将导数估计集中在像素上。但另一个很好的理由是它是central difference公式,并且你可以在数学上证明它在真正的导数的同一性中给出的误差小于[-1 1]。

[1 2 1]用于过滤噪音,如mbrenon所说。这些特定数字运作良好的原因是它们是高斯​​的近似值,它是唯一的滤波器,不会引入伪像(尽管从索贝尔的文章中看,这似乎是巧合)。现在,如果您想减少噪音,并且要找到水平导数,则需要在垂直方向上进行滤波,以便最小化导数估计值。将transpose([1 2 1])[-1 0 1]进行对比,我们得到了Sobel算子。即:

[1]            [-1 0 1]
[2]*[-1 0 1] = [-2 0 2]
[1]            [-1 0 1]

答案 2 :(得分:3)

对于2D图像,您需要一个遮罩。说这个面具是:

[ a11 a12 a13; 
  a21 a22 a23;
  a31 a32 a33 ]

Df_x(沿x的梯度)应该从Df_y(y沿梯度)旋转90°产生,即掩模应该是:

[ a11 a12 a11; 
  a21 a22 a21;
  a31 a32 a31 ]

现在,如果我们想要减去中间像素前面的信号(这就是离散 - 减法的区别),我们想要为减法的两边分配相同的权重,即我们的掩模变为:

[  a11 a12 a11; 
   a21 a22 a21;
  -a11 -a12 -a11 ]

接下来,权重之和应该为零,因为当我们有一个平滑的图像(例如全部255个)时,我们希望得到零响应,即得到:

[  a11 a12 a11; 
   a21 -2a21 a21;
  -a31 -a12 -a31 ]

在图像平滑的情况下,我们期望沿X轴的区分产生零,即:

[  a11 a12 a11; 
   0 0 0;
  -a31 -a12 -a31 ]

最后,如果我们正常化,我们得到:

[  1 A 1; 
   0 0 0;
  -1 -A -1 ]

您可以将A设置为您想要的任何实验。因子2给出了原始的Sobel滤波器。