当将 Sobel 算子应用于 X 和 Y 方向的图像并atan2
从生成的 X/Y 向量计算角度 ( ) 时,我似乎以 45 度的步长获得梯度方向。Sobel 是否只能以 45 度的步长产生 8 个方向,或者我应该得到精确的角度还是可能是舍入误差?
我使用 sobel 卷积Gx
并Gy
在此处提到https://en.wikipedia.org/wiki/Sobel_operator
当将 Sobel 算子应用于 X 和 Y 方向的图像并atan2
从生成的 X/Y 向量计算角度 ( ) 时,我似乎以 45 度的步长获得梯度方向。Sobel 是否只能以 45 度的步长产生 8 个方向,或者我应该得到精确的角度还是可能是舍入误差?
我使用 sobel 卷积Gx
并Gy
在此处提到https://en.wikipedia.org/wiki/Sobel_operator
是的,使用分类 Sobel 运算符。让我们试着理解你在这里做什么:
用于检测垂直线的 Sobel 算子如下所示:
[-1 0 1
-2 0 2
-1 0 1]
如果将其应用于像素(将其放在像素的顶部,并使用相邻像素中的值,然后将所有内容相加),则仅当右侧的像素与像素中的像素具有不同的值时,它才会具有非零值左边。如果是这种情况,则意味着存在垂直边缘。
下面是 45 度 Sobel 算子:
[-2 -1 0
-1 0 1
0 1 2]
如果您了解垂直的工作原理,这应该很容易理解。当该矩阵的对角线具有不同的值时,将出现最大值,即 45 度边。
在继续之前,让我们注意@ImanolLuengo 在评论中提到的一件事:45 度 Sobel 算子实际上会看到 30 度斜率,它只会给它一个较小的值。它会增强它。如果你愿意,你可以自己测试一下。
现在,使用 3x3 矩阵,您可以看到很难获得 30 度边缘,主要是因为我们使用的内核是谨慎且小 (3x3) 的事实不允许我们创建一个增强其他角度。
然而,使用与 Sobel 算子相同的逻辑,我们可以考虑一个更大的内核,它可以增强任意角度。
例如以下内核将主要增强 30 度:
[1 1 1 1 0
1 1 0 0 0
0 0 0 -1 -1
0 -1 -1 -1 -1]
它是“手动近似的 kenrel,因为正如您在 Sobel 中指出的那样,某些内核元素的数字比其他内核元素大。这个数字的规则是:您想要检测的边缘方向上的值越高,值越高在那些实际上通过内核中心的那些。
这不会是一个 Sobel 算子,但您可以组成任何可以完成您想要的工作的内核。