在 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 = 765
和 Gy = -765
,将这些量代入上述等式得到:
>> Gy = 765;
>> Gx = -765;
>> Gdir = atan2(-Gy,Gx)*180/pi
Gdir =
-135
这是有道理的,因为梯度方向对应于变化率最大的方向。 -135 度意味着我们指向西南方向,这在我们从暗像素到亮像素的过程中确实有意义。
现在,如果您查阅第三个示例图像,imgradient
报告的角度确实是正确的。简单地从暗区画一条线到亮区,看看它与 x
轴成什么角度,它与向右增加的列对齐。当我们从底部移动到顶部以跟随黑暗区域和光线时,第一个角度 +90 度是有意义的。这与图像反转的情况类似。第三种情况是我们之前看到的,第四种情况只是第三种情况旋转了 180 度,所以从黑暗到光明的方向角度自然现在是 +45 度,而不是之前的 -135 度。
我正在查找图像的渐变。现在我只使用 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 = 765
和 Gy = -765
,将这些量代入上述等式得到:
>> Gy = 765;
>> Gx = -765;
>> Gdir = atan2(-Gy,Gx)*180/pi
Gdir =
-135
这是有道理的,因为梯度方向对应于变化率最大的方向。 -135 度意味着我们指向西南方向,这在我们从暗像素到亮像素的过程中确实有意义。
现在,如果您查阅第三个示例图像,imgradient
报告的角度确实是正确的。简单地从暗区画一条线到亮区,看看它与 x
轴成什么角度,它与向右增加的列对齐。当我们从底部移动到顶部以跟随黑暗区域和光线时,第一个角度 +90 度是有意义的。这与图像反转的情况类似。第三种情况是我们之前看到的,第四种情况只是第三种情况旋转了 180 度,所以从黑暗到光明的方向角度自然现在是 +45 度,而不是之前的 -135 度。