卷积
[-3 -5 0 5 3] * A
是actual derivative 的近似值。因为A 是采样的,所以我们无法知道真正的导数。我们需要一个离散的近似值。一种常见的方法是finite difference method,其中一种简单的方法是获取后续元素之间的差异:A[x+1,y]-A[x,y]。这就是在离散情况下填写导数极限方程时得到的结果。 Lim h->0 变为 h=1,没有更小的间距。可以使用卷积计算这种差异:
[1 -1] * A
此操作在两个像素之间的位置产生导数。为了克服这个问题,可以使用中心差异:(A[x+1,y]-A[x-1,y])/2,或以卷积形式:
[1/2 0 -1/2] * A
通过与derivative of the Gaussian 进行卷积可以获得进一步的改进。在平滑(正则化)滤波器方面,高斯是某种最优的。此外,卷积具有属性:d/dx (A * G) = A * d/dx G。也就是说,用高斯导数对图像进行卷积与经过高斯平滑的图像的true导数相同。您可以将这样的一维卷积编写为:
[0.013 0.108 0.242 0.0 -0.242 -0.108 -0.013] * A
请注意,最好将列与高斯进行卷积,以保持各向同性。但我们暂时忽略它。
出于某种原因,计算机视觉社区的人们似乎对浮点值过敏(这在最近得到了很大改进,但总会有人认为用整数值计算卷积更便宜)。所以看起来你链接的页面,他们用一个近似它的整数值内核替换了高斯内核的实际导数。这导致[3 5 0 -5 -3]。他们还设法反转这些值,从而得到一个近似于-d/dx 的运算。
他们后来使用 Gabor 来确定方向进一步表明他们并不真正知道自己在做什么,因为 Gabor 对真实梯度的逼近比使用高斯导数所能做的更差。
简而言之,如果要计算导数,请执行以下操作:
A * d/dx G(x) * G(y)
(G(x) 是一维高斯函数x 的函数,即水平向量,G(y) 是其转置的函数;直接对d/dx G(x) 进行采样,而不是对G(x) 进行采样并计算其有限差分导数) .
要计算沿y 轴的导数,请执行相同的操作,但使用G(y) 内核的导数。
实际的实施建议取决于您的语言。 Here is some advice when using MATLAB。它可能也可以很好地翻译成其他语言。
关于 5x5 扫描线:我不知道这是什么意思。我认为他们以某种方式对图像进行子采样以提高性能。更少的像素 = 更快的计算。