在 MATLAB 中使用 imgradient 时如何解释梯度的方向?

How do I interpret the orientation of the gradient when using imgradient in MATLAB?

我正在查找图像的渐变。现在我只使用 5 x 5 的图像。我更感兴趣的是找到梯度的方向,但我没有在纸上手动获得结果,因为我使用 MATLAB 函数 imgradient 得到它们。请参考以下图像以了解有关输入图像和此处用于查找图像梯度的 Sobel 滤波器的更多信息。此处使用的 3 x 3 sobel 运算符之一是我使用函数

得到的
f1 = fspecial('sobel');

而另一个是通过转置 f1.

得到的

请注意,我试图在这里找到一个被红色圆角的像素的方向。在前两种情况下,我的结果与我使用 imgradient 函数获得的结果相匹配,但在第三种情况下,imgradient 给出了 -135 度,而我得到的是 -45。请帮我找出错误。

另外请说明如何解释如下图所示的渐变方向。

您的计算是正确的,但强烈建议您不要使用atan(y/x)定义,因为此计算无法识别角的象限渐变位于其中。对您的组件执行 atan(y/x) 会错误地将角度报告为 -45 度,而这是不正确的。您应该改用 atan2

现在 imgradient 的内部结构非常简单。我想指出 imgradient 报告的角度假设 y 坐标从下到上增加。此外,imgradient 应报告指向最大变化率的方向角。在图像的情况下,这指向我们从暗像素到亮像素的方向。

首先调用 imgradientxy,如果您向 imgradient 提供 sobel 标志,则调用 fspecial('sobel')。事实上,imgradientxy 的这一部分是需要记住的重要内容(从第 75 行开始:MATLAB R2015a):

case 'sobel'
    h = -fspecial('sobel'); %// Align mask correctly along the x- and y- axes
    Gx = imfilter(I,h','replicate'); %'
    if nargout > 1
        Gy = imfilter(I,h,'replicate');
    end

请注意,fspecial 输出的 negative 与该行提供的注释一样执行。这是为了确保检测水平边缘(即 Gy)的掩码是 y-down(这在计算机图形学中是众所周知的)。具体来说,图像的原点在左上角而不是左下角。

这是坐标系在 y-down:

中的布局方式的图示

来源:Wikipedia - Rotation Matrix

因此,在寻找方向时,还需要确保渐变方向的角度是相对于 y-up 坐标系的我们习惯了什么。因此,当您找到渐变的方向角度时,您需要在计算角度之前 取反 坐标 y 以便角度相对于标准约定.

求你求的梯度的定义是y坐标自下而上递增的常规系统。否定是必需的,事实上,如果您检查 imgradient 的源代码,这正是代码(版本 R2015a)的第 127 行所做的事情:

Gdir = atan2(-Gy,Gx)*180/pi; %// Radians to degrees

你可能会问自己为什么需要否定掩码并在找到方向后再次否定 y 坐标。原因是因为需要修改掩码才能正确捕获梯度的大小,所以我们对掩码进行一次取反并找到梯度大小,然后我们取反 y 坐标以便我们可以找到相对于到常规坐标系。

在你的例子中,给定 Gx = 765Gy = -765,将这些量代入上述等式得到:

>> Gy = 765;
>> Gx = -765;
>> Gdir = atan2(-Gy,Gx)*180/pi

Gdir =

  -135

这是有道理的,因为梯度方向对应于变化率最大的方向。 -135 度意味着我们指向西南方向,这在我们从暗像素到亮像素的过程中确实有意义。

现在,如果您查阅第三个示例图像,imgradient 报告的角度确实是正确的。简单地从暗区画一条线到亮区,看看它与 x 轴成什么角度,它与向右增加的列对齐。当我们从底部移动到顶部以跟随黑暗区域和光线时,第一个角度 +90 度是有意义的。这与图像反转的情况类似。第三种情况是我们之前看到的,第四种情况只是第三种情况旋转了 180 度,所以从黑暗到光明的方向角度自然现在是 +45 度,而不是之前的 -135 度。