代码之家  ›  专栏  ›  技术社区  ›  Royi

一维高斯插值到二维高斯

  •  2
  • Royi  · 技术社区  · 15 年前

    假设我有一个一维高斯函数。 它的长度是600。

    我想把它插值到600 x 600大小的二维高斯。

    这是我写的代码(otfx是高斯函数,otf-2d插值函数):

    [x, y] = meshgrid([-300:299], [-300:299]);
    r = sqrt((x .^ 2) + (y .^ 2));
    
    OTF = interp1([-300:299], OTFx, r(:), 'spline');
    OTF = reshape(OTF, [600, 600]);
    

    问题是我最后会超调: alt text http://i39.tinypic.com/259et0g.png

    我怎样才能预防呢? 单调下降函数有更好的插值算法吗?

    3 回复  |  直到 15 年前
        1
  •  5
  •   Leo Alekseyev    15 年前

    编辑:根据你的澄清,很清楚发生了什么。您正在尝试对超出可用数据范围的函数进行插值,即从插值到外推。样条曲线会导致你观察到的超调。解决方法很简单,就是确保1d函数的值在区间[min(r),max(r)]内。注意,在原始数据中,max(r)约为424,而您正在插值的函数是在范围[-300299]上定义的。

    % Simulated overshoot, see left figure:
    x1d = [-300:299];
    [x,y]=meshgrid(x1d,x1d);
    r = sqrt(x.^2+y.^2);
    gsn1d = exp(-x1d.^2/500);
    lowpass = @(x)(x1d > -x & x1d < x);
    gsn1dcutoff = ifft(fftshift(lowpass(10).*fftshift(fft(gsn1d))));
    plot(gsn1dcutoff)
    OTF2d = reshape(interp1(x1d,gsn1dcutoff,r(:),'spline'),[length(x1d),length(x1d)]);
    mesh(OTF2d)
    
    % Quick and dirty fix, see right figure:
    x1dExtended = linspace(min(x1d*sqrt(2)),max(x1d*sqrt(2)),ceil(length(x1d)*sqrt(2)));
    gsn1dE = exp(-x1dExtended.^2/500);
    % ^^^ note that this has 600*sqrt(2) points and is defined on the diagonal of your square.   Now we can low-pass filter in the freq. domain to add ripple in space domain:
    lowpass = @(x)(x1dExtended > -x & x1dExtended < x);
    gsn1dcutoff = -real(ifft(fftshift(lowpass(10).*fftshift(fft(gsn1dE)))));
    plot(gsn1dcutoff)
    OTF2d = reshape(interp1(x1dExtended,gsn1dcutoff,r(:),'spline'),[length(x1d),length(x1d)]);
    mesh(OTF2d)
    

    alt text http://img54.imageshack.us/img54/8255/clipboard01vz.png

        2
  •  2
  •   AVB    15 年前

    利奥的诊断是对的。我想建议一个更简单(我希望)的方法:做你想做的事情(基本上是围绕对称轴旋转高斯函数)并在600x600平方中得到合理的答案,你需要高斯函数600*sqrt(2)=849像素长。如果你能做到,那么所有进一步的thttp://stackoverflow.com/questions/2443046/interpolating-1d-gaussian-into-2d-gaussianrickery都是不必要的。

    编辑 :换句话说:如果围绕圆心旋转600像素宽的物体,则得到直径为600像素的圆。你想覆盖一个600x600 广场 . 为此,需要一个直径为849像素的圆,因为这是正方形的对角线。

        3
  •  0
  •   meduz    15 年前

    在高斯的特定情况下,可以使用高斯是可分离的这一事实来计算高斯:

    OTF2(x,y) = exp( - x^2 - y^2) = exp( - x^2) * exp( - y^2) = OTFx(x) * OTFx(y)
    

    所以你仍然只需要把otfx存储在内存中。