0

我在matlab工作,最近我在做图像处理方面的研究。这次我正在实施一篇研究论文this paper,其中我遇到了存储精度超过一倍的问题。请检查该论文的等式6。

我在以下代码中遇到问题..

img = imread('Einstein.bmp');
exponent = double(zeros(size(img,1),size(img,2)));
s = double(zeros(size(img,1),size(img,2)));
sigma=1;
for i=1:size(img,1)
    for j=1:size(img,2)
        exponent(i,j) = double(((i^2)+(j^2))/(2*(sigma^2)));
        s(i,j) = double(exp(-exponent(i,j)));
    end
end

在某些值之后,s(i,j) 为所有值给出 0,但该值不应为 0。我怎样才能避免这个问题?

4

2 回答 2

0

matlab 似乎只使用 64 位双精度,但您可能对 matlab 可用的任意 精度 库之一感到幸运。

于 2013-09-11T08:01:19.770 回答
0

查看您的代码,您似乎正在尝试创建一个以 (0,0) 为中心的二维高斯函数。您使用的内核宽度非常小:sigma=1看到您正在计算整个图像像素网格上的函数。所以难怪除了矩阵左上角的一小部分之外,你得到的都是零S

这是创建以中间为中心的内核的更有效方法:

% 100x100 grid
r = 100; c = 100;
[x,y] = ndgrid(1:r,1:c);

% sigma = 20
sigma = max([r c])/5;

% 2D gaussian function
z = sum(bsxfun(@minus, [x(:) y(:)], [r c]./2).^2, 2);
z = exp(-z ./ (2*sigma^2)) ./ (sigma^2 * 2*pi);
z = reshape(z, [r c]);

如果您有权访问统计工具箱,请使用mvnpdf它写为:

z = mvnpdf([x(:) y(:)], [r c]./2, eye(2)*sigma^2);
z = reshape(z, [r c]);

或者如果您有图像处理工具箱,只需使用fspecial

z = fspecial('gaussian', [r c], sigma);

结果:

imshow(z, 'DisplayRange',[], 'InitialMag','fit')
axis on, colorbar

2d_gaussian

请注意,矩阵已归一化,因此积分为 1(因此值较小)。[0,1]这就是为什么我在显示为图像时关闭了默认范围。

您也可以[0,1]使用以下方法简单地将其映射到范围:z = (z - min(z(:))) ./ range(z(:))

这是作为表面查看时的结果矩阵:

surf(x,y,z)
axis vis3d

2d_gauss_surface

于 2013-09-11T23:29:59.143 回答