梯度和imgradient之间有什么区别?

6

我希望计算图像I的梯度。我有两个选项:

[Gx, Gy] = gradient(I);
g = sqrt(Gx.^2+Gy.^2);

[g,~] = imgradient(I, 'sobel');

我的问题是

  1. 第一选项中使用的梯度方法是什么?

  2. 使用Sobel方法找到梯度的好处是什么?

谢谢

这是我尝试过的内容

I=zeros([128 128]);
I(50:100,50:100)=100;
[Gx, Gy] = gradient(I);
g1 = sqrt(Gx.^2+Gy.^2);
[g2,~] = imgradient(I, 'sobel');
subplot(121);imshow(g1,[]);title('First option')
subplot(122);imshow(g2,[]);title('Second option')

enter image description here

当噪声添加到图像中时,差异将更加明显。
I=zeros([128 128]);
I(50:100,50:100)=100;
%% Add noise image;
noiseStd=5;
I_noise = I + (noiseStd * randn([128, 128]));
[Gx, Gy] = gradient(I_noise);
g1 = sqrt(Gx.^2+Gy.^2);
[g2,~] = imgradient(I_noise, 'sobel');
subplot(121);imshow(g1,[]);title('First option')
subplot(122);imshow(g2,[]);title('Second option')

enter image description here

作为可视化,第二个选项提供了更多的亮度值。

1
你尝试过比较吗?主要区别在于一个是针对图像工具箱的,另一个适用于任何表面。 - Ander Biguri
是的,我已经更新了。请查看我的更新后的问题。 - Jame
嗨!考虑接受一个答案作为有效的。 - Ander Biguri
2个回答

8

区别在于确实是'Sobel'算子。Sobel算子是一个矩阵,与图像卷积以计算其方向梯度。

Sobel算子的定义如下(来自维基百科):

enter image description here

gradient 只是方向上的差异,可以将其理解为 gradient 的作用。
Gx=[ 0 0 0;                Gx=[ 0 -1 0;
    -1 0 1;         and         0  0 0;
     0 0 0]                     0  1 0];

这种差异是因为当有一张图片时,人们知道它是一个连续域的离散化。Sobel算子有助于考虑发生在给定像素“周围”的事情。

那么,如果我只将梯度而不考虑其方向视为上述代码中的梯度,这两个梯度有什么不同? - Jame
@user8430 imgradient 只会输出 sqrt(Gx^2+Gy^2),而 gradient 则会分别输出两个梯度。就是这样。 - Ander Biguri
从我的结果来看,很明显中心差分法比Sobel方法产生更多的噪声。因此,与中心差分法相比,Sobel方法使用不同的系数设计核实现更好的噪声抑制。你同意我的观点吗? - Jame
@user8430 当然可以。因为它不仅考虑了像素的两个邻居,而是六个邻居,因此噪声会被“平均化”一些。 - Ander Biguri
1
@user8430 很棒的回答,但是补充一下Ander所说的“噪声有点被平均掉了”,请注意Sobel在中心部分的权重更大。这几乎像是一个(低分辨率的)高斯平滑滤波器。Prewitt滤波器(真正的平均值)将使用Gy=[1,1,1;0,0,0;-1,-1,-1],虽然这会去除一定量的噪声,但结果与Sobel不同。把这些滤波器看作预卷积的滤波器。由一个边缘检测器[1,0,-1]* smoothing_function组成。因此,请想象平均模糊和高斯模糊之间的差异。希望这能给您更多见解。 - andrew

8

gradient 函数仅使用中心差分,而imgradient 函数则提供了多种选择,例如 'central' 或默认的 'sobel'。使用第一种选项,imgradient 函数与 gradient 函数的效果相同:

I=zeros([128 128]);
I(50:100,50:100)=100;
%% Add noise image;
noiseStd=5;
I_noise = I + (noiseStd * randn([128, 128]));
[Gx, Gy] = gradient(I_noise);
g1 = sqrt(Gx.^2+Gy.^2);
[g2,~] = imgradient(I_noise, 'sobel');
[g3,~] = imgradient(I_noise, 'central');
subplot(131);imshow(g1,[]);title('gradient')
subplot(132);imshow(g2,[]);title('imgradient sobel')
subplot(133);imshow(g3,[]);title('imgradient central')

enter image description here


imgradient提供了五个选项:

  • 'sobel' Sobel梯度算子(默认)
  • 'prewitt' Prewitt梯度算子
  • 'central' 中心差分梯度:dI/dx = (I(x+1) - I(x-1))/2
  • 'intermediate'中间差分梯度:dI/dx = I(x+1) - I(x)
  • ‘roberts' Roberts梯度算子

文档解释如下:

imgradient对于每个列出的梯度方法采用的算法是首先计算沿着x轴和y轴的方向梯度,GxGy。x轴沿着从右到左的列定义,y轴沿着从上到下的行定义。然后从它们的正交分量GxGy计算梯度幅值和方向。


感谢您提供中心差分的示例。那么,Sobel算子有什么好处呢?正如小猪所说,它可以提供更平滑的图像。 - Jame
@user8430 这个问题超出了StackOverflow的范围,而且我也不确定答案。你需要对单个算法进行一些研究。 - Robert Seifert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接