计算图像的梯度向量场

17

我想读入一张图像——一个圆形的图片,并计算该图像的梯度向量场(即指向圆周并与圆周垂直的向量)。我的逻辑有些不对,但我有:

clear all;
im = im2double(imread('littlecircle.png'));
im = double(im);
[nr,nc]=size(im);
[dx,dy] = gradient(im);
[x y] = meshgrid(1:nc,1:nr);
u = x;
v = y;
quiver(x,y,u,v)

如果我仅按上述方式操作,我会得到一个向量场,但它只是一个空网格的梯度(即只有 y=x 的梯度向量场)。实际上我想使用

[dx,dy] = gradient(im);

如何检测图像中圆的边缘,然后计算由圆在图像中引起的梯度向量场。显然,将u=x和v=y分配给我只会给出直线的向量场 - 因此,基本上我想将图像的梯度嵌入到向量u和v中。我该怎么做?

我的结果

我遇到错误的图像


你能发布littlecircle.png吗? - Andrey Rubshtein
1个回答

15
您在代码中犯了一个错误(除此之外,它运行良好)。您应该替换以下内容:
u = dx;
v = dy;

不是

u = x;
v = y;

它对于this图像的工作非常出色!

编辑: 如果您想要将向量叠加在图像上,则执行以下操作:

clear all;
im = imread('littlecircle.png');
[nr,nc]=size(im);
[dx,dy] = gradient(double(im));
[x y] = meshgrid(1:nc,1:nr);
u = dx;
v = dy;
imshow(im);
hold on
quiver(x,y,u,v)

注意,我没有将im转换为double,因为它在imshow中不会正确显示(需要uint8)。根据您的图像尺寸,您可能希望放大以查看梯度向量。
下面是图像上叠加的矢量缩小区域:

Gradient vectors of a circle in an image

更好的质量图像在http://i.stack.imgur.com/fQbwI.jpg

我不确定您想做什么。在我发布的代码中,向量确实从圆形向外指(我附上了放大的截图)。当然,由于您有一个在离散空间(图像)计算梯度的计算例程,由于量化,这些向量不能绝对正常地与圆相切,即不要期望看到“完美”的梯度向量,就像为给定的数学圆分析地计算一样。 - Jorge
1
关于向量场的另一个注意事项。gradient(im)确实返回一个向量场。例如,在[dx,dy] = gradient(im)中,dx和dy是与im相同尺寸的矩阵。例如,如果im为200x300,则dx,dy也是如此。它们表示每个点处grad向量的x和y分量。因此,对于图像中的点(123,245),梯度向量为v = [dx(123,245),dy(123,245)];当然,由于您想要使用向量,因此还需要基空间即x,y矩阵的坐标。 - Jorge
谢谢Jorge - 在你的帮助下,我终于到达了目的地。Matlab使用向量的方式一直让我感到困惑。你的解释帮了我很多! - brucezepplin
1
好的,我知道问题出在哪里了。你发布的图像是RGB格式,而代码只能处理灰度图像。因此,你需要使用以下代码进行转换:im = rgb2gray(imread('littlecircle.png')),这样就可以正常运行了。 - Jorge
@Jorge 你能解释一下你之前的评论吗?我想解决同样的问题。评论如下:gradient(im)会返回一个向量场。例如,在[dx,dy] = gradient(im)中,dx和dy是与im相同尺寸的矩阵。例如,如果im是200x300,则dx,dy也是如此。它们表示每个点处梯度向量的x和y分量。因此,对于图像中的点(123,245),梯度向量为v=[dx(123,245),dy(123,245)];当然,由于您想使用向量场,您还需要基空间即x,y矩阵的坐标。 - Autonomous
显示剩余10条评论

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