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

Alc*_*ott 29 image-processing computer-vision edge-detection

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

[-1 0 1]
[-2 0 2]
[-1 0 1]
Run Code Online (Sandbox Code Playgroud)

我不太了解它的两件事,

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

[-1 1]
[-1 1]
[-1 1]
Run Code Online (Sandbox Code Playgroud)

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

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

mbr*_*non 56

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

事实上,我们可以想到的更简单的梯度算子比你上面提到的更简单:

[-1 1]
Run Code Online (Sandbox Code Playgroud)

尽管它的简单性,该运营商拥有第一个问题:当你使用它,你计算的梯度之间的两个位置,而不是一个位置.如果你将它应用到2个像素(x,y)(x+1,y),你有没有计算在位置的梯度(x,y)(x+1,y)?事实上,你所计算的是位置上的渐变,(x+0.5,y)使用半像素并不是很方便.这就是我们在中间加零的原因:

[-1 0 1]
Run Code Online (Sandbox Code Playgroud)

将此应用于像素(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]
Run Code Online (Sandbox Code Playgroud)

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

[-1 0 1]
[-2 0 2]
[-1 0 1]
Run Code Online (Sandbox Code Playgroud)

篡改系数可能会导致其他梯度运算符,例如Scharr运算符,这会给中心行增加一点权重:

[-3  0 3 ]
[-10 0 10]
[-3  0 3 ]
Run Code Online (Sandbox Code Playgroud)

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

  • *“只有您的想象力是创造新事物的极限,只要它满足您的需求......”* - +1。 (2认同)

Bul*_*ull 18

编辑 Sobel操作员看起来如此的真正原因可以通过阅读索贝尔本人的一篇有趣文章来找到.我对本文的快速阅读表明索贝尔的想法是通过平均水平,垂直和对角线中心差异来获得梯度的改进估计.现在,当您将渐变分为垂直和水平分量时,对角线中心差异包含在两者中,而垂直和水平中心差异仅包含在一个中.两个避免重复计算对角线因此应该具有垂直和水平的一半权重.1和2的实际权重仅适用于定点算术(实际上包括16的比例因子).

我主要赞同@mbrenon,但在评论中有几点难以提及.

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

确实,使用的一个很好的理由[-1 0 1]是它将导数估计集中在像素上.但另一个很好的理由是它是中心差分公式,并且你可以在数学上证明它在真实导数的同一性中给出的误差小于[-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]
Run Code Online (Sandbox Code Playgroud)