Matlab:一阶导数边缘检测,关于梯度
Matlab: First derivative edge detection, about gradients
我正在编写一个程序,要求用户在 Prewitt 和 之间进行选择Sobel 图像过滤器,用于检测图像对象的边缘。我必须使用他们的过滤器模板,而不是 edge
函数。用户还告诉他是否要检测 'horizontal'、'vertical' 或 'diagonal' 边缘。我的问题是理论上的,而不是关于编程的。
在我的笔记中,我得到了计算每个像素梯度大小的方法,它通常近似为 sqrt(Gx^2 + Gy^2)
,其中 Gx
是垂直导数,Gy
水平导数。但是,如果我只计算水平边缘,Gx
的值是多少?如果我只寻找垂直边缘,Gy
的值?
我自己猜不出来
这很简单。您关心的是使用掩码执行图像过滤,其中每个掩码都是导数过滤器。使用这种方法,knedlsepp 是正确的,因为这样做只会找到相对于给定方向的偏导数。您可以指定一个掩码来检测水平边缘,另一个掩码用于检测垂直边缘。
Gx
代表垂直边缘响应使用垂直微分滤波器,Gy
代表水平[=63] =] 使用水平微分滤波器的边缘响应。要获得响应,您需要拍摄图像并使用任何蒙版通过 2D 卷积对其进行过滤。
接下来,您将将 两个响应组合在一起以获得整体幅度响应。然而,edge
在引擎盖下执行了大量噪声清除,还执行阈值处理以获得最终响应。简单地计算幅度并不是 edge
所做的事情的全部。
无论如何,为了检测水平边缘,Prewitt mask 看起来像这样:
Gy_prewitt =
-1 -1 -1
0 0 0
1 1 1
使用上述掩码执行过滤找到水平边缘响应,或Gy
。
为了找到垂直边缘响应或 Gx
,您只需 转置 上面的掩码并找到滤波器响应,所以:
Gx_prewitt =
-1 0 1
-1 0 1
-1 0 1
Sobel 掩码与 Prewitt 掩码略有不同。掩码的中央行(对于垂直)或列(对于水平)有更多的夸张,并且加权两倍。水平遮罩为:
Gy_sobel =
-1 -2 -1
0 0 0
1 2 1
同样,Sobel 的垂直遮罩定义为:
Gx_sobel =
-1 0 1
-2 0 2
-1 0 1
需要注意的是mask中所有系数的总和等于0,实际上是任何一个看到的边缘检测mask的属性在实践中。
现在,要确定整体边缘响应,您需要对每个水平、Gy
和垂直 Gx
进行过滤响应,并对每个相应像素应用幅度运算:
out = sqrt(Gx.^2 + Gy.^2);
如果您想更直观地解释为什么 Sobel 掩码与 Prewitt 掩码略有不同,我鼓励您看一下这个 post。它提供了一个很好的解释以及一个很好的图表,说明如果你不能使用内置的卷积方法,如何自己实现过滤操作:
http://blog.saush.com/2011/04/20/edge-detection-with-the-sobel-operator-in-ruby/
这是图表:
基本上,对于您要在图像中过滤的每个像素,提取一个 3 x 3 邻域并在邻域中的这些像素与您想要的过滤器之间执行加权和。在这种情况下,这将是 Sobel 垂直边缘检测器。
祝你好运!
我正在编写一个程序,要求用户在 Prewitt 和 之间进行选择Sobel 图像过滤器,用于检测图像对象的边缘。我必须使用他们的过滤器模板,而不是 edge
函数。用户还告诉他是否要检测 'horizontal'、'vertical' 或 'diagonal' 边缘。我的问题是理论上的,而不是关于编程的。
在我的笔记中,我得到了计算每个像素梯度大小的方法,它通常近似为 sqrt(Gx^2 + Gy^2)
,其中 Gx
是垂直导数,Gy
水平导数。但是,如果我只计算水平边缘,Gx
的值是多少?如果我只寻找垂直边缘,Gy
的值?
我自己猜不出来
这很简单。您关心的是使用掩码执行图像过滤,其中每个掩码都是导数过滤器。使用这种方法,knedlsepp 是正确的,因为这样做只会找到相对于给定方向的偏导数。您可以指定一个掩码来检测水平边缘,另一个掩码用于检测垂直边缘。
Gx
代表垂直边缘响应使用垂直微分滤波器,Gy
代表水平[=63] =] 使用水平微分滤波器的边缘响应。要获得响应,您需要拍摄图像并使用任何蒙版通过 2D 卷积对其进行过滤。
接下来,您将将 两个响应组合在一起以获得整体幅度响应。然而,edge
在引擎盖下执行了大量噪声清除,还执行阈值处理以获得最终响应。简单地计算幅度并不是 edge
所做的事情的全部。
无论如何,为了检测水平边缘,Prewitt mask 看起来像这样:
Gy_prewitt =
-1 -1 -1
0 0 0
1 1 1
使用上述掩码执行过滤找到水平边缘响应,或Gy
。
为了找到垂直边缘响应或 Gx
,您只需 转置 上面的掩码并找到滤波器响应,所以:
Gx_prewitt =
-1 0 1
-1 0 1
-1 0 1
Sobel 掩码与 Prewitt 掩码略有不同。掩码的中央行(对于垂直)或列(对于水平)有更多的夸张,并且加权两倍。水平遮罩为:
Gy_sobel =
-1 -2 -1
0 0 0
1 2 1
同样,Sobel 的垂直遮罩定义为:
Gx_sobel =
-1 0 1
-2 0 2
-1 0 1
需要注意的是mask中所有系数的总和等于0,实际上是任何一个看到的边缘检测mask的属性在实践中。
现在,要确定整体边缘响应,您需要对每个水平、Gy
和垂直 Gx
进行过滤响应,并对每个相应像素应用幅度运算:
out = sqrt(Gx.^2 + Gy.^2);
如果您想更直观地解释为什么 Sobel 掩码与 Prewitt 掩码略有不同,我鼓励您看一下这个 post。它提供了一个很好的解释以及一个很好的图表,说明如果你不能使用内置的卷积方法,如何自己实现过滤操作:
http://blog.saush.com/2011/04/20/edge-detection-with-the-sobel-operator-in-ruby/
这是图表:
基本上,对于您要在图像中过滤的每个像素,提取一个 3 x 3 邻域并在邻域中的这些像素与您想要的过滤器之间执行加权和。在这种情况下,这将是 Sobel 垂直边缘检测器。
祝你好运!