简体   繁体   English

使用FFT进行高斯模糊

[英]Gaussian blur using fft

I implement a method that blurs an image using a Gaussian like this: 我实现了一种使用高斯模糊图像的方法,如下所示:

- image I , size = WxH
- kernel K , size = MxM
- padded the kernel PD to the size of the image
  i.e for an image 5x5 and a kernel 3x3 after padding the kernel looks like:
    0 0 0 0 0
    0 x x x 0
    0 x x x 0
    0 x x x 0
    0 0 0 0 0 
where X is the value from the original kernel
- performed 2d fft on the padded kernel PD (FFT_K)
- performed 2d fft on the image I (FFT_I)
- multiplied FFT_I * FFT_K (FFT_RES)
- perfomed fft on FFT_RES
- shifted the FFT_RES (RESULT)

The result contains some aliasing on the edges. 结果在边缘上包含一些混叠。

Here is the result: 结果如下:

在此处输入图片说明

If you notice in the right image you will see that it is aliased in both dimensions. 如果在正确的图像中注意到,则将在两个维度上看到它的别名。

Is the above algorithm correct? 以上算法正确吗?

The implementation is with C++ and fftw3. 该实现使用C ++和fftw3。

Your above algorithm is correct with a slight caviate. 您的上述算法正确无误。

When you pad your image with 0's, those zeros are actually used in the convolution. 当您用0填充图像时,这些零实际上会在卷积中使用。 In the FFT space, this will add huge high freqency components around the edge of the image. 在FFT空间中,这将在图像边缘周围添加巨大的高频分量。 In non-FFT space, this means that, up to 1-the kernel size on the edge, the 0's are rolled in, which will give you odd looking results on the edge. 在非FFT空间中,这意味着,边缘上的内核大小最大为1时,将滚动0,这将在边缘上给您带来奇怪的结果。 People typically handle this in two ways: 人们通常以两种方式处理此问题:

  1. Simply throw out 1 kernel size border around the image after convolution. 卷积后,只需在图像周围抛出1个内核大小的边界即可。
  2. Mirror the edge into the pad instead of filling it with zeros. 将边缘镜像到垫中,而不用零填充。

For best results, I'll often do both 1 and 2 (to get an actual image and to eliminate the high frequency edge in the Fourier space). 为了获得最佳结果,我经常会同时进行1和2(以获取实际图像并消除傅立叶空间中的高频边缘)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM