对于图像导数计算,Sobel 算子是这样的:
[-1 0 1]
[-2 0 2]
[-1 0 1]
我不太明白关于它的两件事,
1.为什么中心像素是0?我不能只使用下面这样的运算符吗?
[-1 1]
[-1 1]
[-1 1]
2.为什么中间行是其他行的2倍?
我用谷歌搜索了我的问题,没有找到任何可以说服我的答案。请帮我。
对于图像导数计算,Sobel 算子是这样的:
[-1 0 1]
[-2 0 2]
[-1 0 1]
我不太明白关于它的两件事,
1.为什么中心像素是0?我不能只使用下面这样的运算符吗?
[-1 1]
[-1 1]
[-1 1]
2.为什么中间行是其他行的2倍?
我用谷歌搜索了我的问题,没有找到任何可以说服我的答案。请帮我。
在计算机视觉中,通常没有完美、通用的做事方式。大多数情况下,我们只是尝试一个运算符,查看其结果并检查它们是否符合我们的需求。梯度计算也是如此:Sobel 算子是计算图像梯度的众多方法之一,这已在许多用例中证明了它的有用性。
事实上,我们能想到的更简单的梯度算子比你上面建议的更简单:
[-1 1]
尽管它很简单,但这个运算符有第一个问题:当你使用它时,你计算的是两个位置之间的梯度,而不是一个位置。如果将其应用于 2 个像素(x,y)
和(x+1,y)
,您是否计算了位置(x,y)
或处的梯度(x+1,y)
?实际上,您计算的是 position 处的梯度(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 ]
这也有数学上的原因,例如这些过滤器的可分离性......但我更喜欢将其视为一个实验发现,它被证明具有有趣的数学特性,因为我认为实验是计算机视觉的核心。只有您的想象力是创造新事物的极限,只要它符合您的需求......
编辑Sobel 运算符看起来那样的真正原因可以通过阅读Sobel 本人的一篇有趣的文章来找到。我对这篇文章的快速阅读表明,Sobel 的想法是通过平均水平、垂直和对角中心差异来改进梯度估计。现在,当您将渐变分解为垂直和水平分量时,对角线中心差异包含在两者中,而垂直和水平中心差异仅包含在一个中。两个避免重复计算对角线因此应具有垂直和水平的一半权重。1 和 2 的实际权重只是方便定点算术(实际上包括 16 的比例因子)。
我主要同意@mbrenon,但有几点很难在评论中提出。
首先,在计算机视觉中,“大多数情况下,我们只是尝试操作员”的方法只是浪费时间,并且与可能取得的结果相比,结果很差。(也就是说,我也喜欢尝试。)
确实,使用的一个很好的理由[-1 0 1]
是它将导数估计集中在像素上。但另一个很好的理由是它是中心差分公式,您可以在数学上证明它在估计真导数时给出的误差低于 [-1 1]。
[1 2 1]
是用来过滤噪声的,如mbrenon,表示。这些特定数字运行良好的原因是它们是高斯的近似值,它是唯一不引入伪影的滤波器(尽管从 Sobel 的文章来看,这似乎是巧合)。现在,如果您想减少噪声并且您正在寻找一个水平导数,您想在垂直方向上进行过滤,以便最小化对导数估计的影响。transpose([1 2 1])
与我们进行卷积[-1 0 1]
得到 Sobel 算子。IE:
[1] [-1 0 1]
[2]*[-1 0 1] = [-2 0 2]
[1] [-1 0 1]
对于 2D 图像,您需要一个蒙版。说这个面具是:
[ a11 a12 a13;
a21 a22 a23;
a31 a32 a33 ]
Df_x(沿 x 的梯度)应由 Df_y(沿 y 的梯度)通过 90o 的旋转产生,即蒙版应为:
[ a11 a12 a11;
a21 a22 a21;
a31 a32 a31 ]
现在,如果我们想减去中间像素前面的信号(这就是离散的差异 - 减法),我们希望为减法的两侧分配相同的权重,即我们的掩码变为:
[ a11 a12 a11;
a21 a22 a21;
-a11 -a12 -a11 ]
接下来,权重的总和应该为零,因为当我们有一个平滑的图像(例如所有 255s)时,我们希望有一个零响应,即我们得到:
[ 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 滤波器。