【问题标题】:Correct implementation of Gaussian blur via FFT通过 FFT 正确实现高斯模糊
【发布时间】:2014-07-06 09:28:12
【问题描述】:

我已经阅读了很多关于高斯模糊和 FFT 的关于 SO 的问题,但没有回答如何实现它的步骤(但有一些类似“这是你的作业”的 cmets)。我想知道,如何正确填充内核并在内核和图像上使用 FFT 和 IFFT。您能否提供一些伪代码或任何语言(如 Java、Python 等)的实现,或者至少提供一些如何理解它的好教程:

1. FFT the image
2. FFT the kernel, padded to the size of the image
3. multiply the two in the frequency domain (equivalent to convolution in the spatial domain)
4. IFFT (inverse FFT) the result

Gaussian blur and FFT复制的步骤

【问题讨论】:

    标签: image-processing filtering fft gaussian gaussianblur


    【解决方案1】:

    Matlab 示例。这应该是您开始的好地方。

    加载图片:

    %Blur Demo
    
    %Import image in matlab default image set.
    origimage = imread('cameraman.tif');
    
    %Plot image
    figure, imagesc(origimage)
    axis square
    colormap gray
    title('Original Image')
    set(gca, 'XTick', [], 'YTick', [])
    

    整个过程:

    %Blur Kernel
    ksize = 31;
    kernel = zeros(ksize);
    
    %Gaussian Blur
    s = 3;
    m = ksize/2;
    [X, Y] = meshgrid(1:ksize);
    kernel = (1/(2*pi*s^2))*exp(-((X-m).^2 + (Y-m).^2)/(2*s^2));
    
    %Display Kernel
    figure, imagesc(kernel)
    axis square
    title('Blur Kernel')
    colormap gray
    
    %Embed kernel in image that is size of original image
    [h, w] = size(origimage);
    kernelimage = zeros(h,w);
    kernelimage(1:ksize, 1:ksize) = kernel;
    
    %Perform 2D FFTs
    fftimage = fft2(double(origimage));
    fftkernel = fft2(kernelimage);
    
    %Set all zero values to minimum value
    fftkernel(abs(fftkernel)<1e-6) = 1e-6;
    
    %Multiply FFTs
    fftblurimage = fftimage.*fftkernel;
    
    %Perform Inverse 2D FFT
    blurimage = ifft2(fftblurimage);
    
    %Display Blurred Image
    figure, imagesc(blurimage)
    axis square
    title('Blurred Image')
    colormap gray
    set(gca, 'XTick', [], 'YTick', [])
    

    图片前:

    后图像:

    请注意,由于零填充没有将内核置于中心位置,因此您会得到一个偏移量。这个答案解释了包装问题。 gaussian blur with FFT

    【讨论】:

    • 很棒的示例代码。我确实有一些建议可以让这变得更好。 (1) 使用我们可以测试的实际图像显示示例结果。您正在将 imread 与我们无权访问的本地图像一起使用。 (2)不要简单的用红色通道转灰度。使用rgb2gray 为您执行此操作。 (3) 如果您有时间,请扩展到彩色图像,您将在每个通道单独执行过滤。 (4) 使用find 将所有零值设置为最小值有点低效。改用逻辑索引:fftkernel(fftkernel == 0) = 1e-6; 你不需要find 这里。
    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2019-02-25
    相关资源
    最近更新 更多