【问题标题】:Gaussian blur using fft使用 fft 进行高斯模糊
【发布时间】:2014-12-10 15:09:16
【问题描述】:

我实现了一种使用高斯模糊图像的方法,如下所示:

- 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)

结果在边缘包含一些锯齿。

结果如下:

如果您注意到正确的图像,您会看到它在两个维度上都有别名。

上述算法正确吗?

使用 C++ 和 fftw3 实现。

【问题讨论】:

  • 只是确认,对于 3x3 内核,“锯齿”(实际上很可能不是)在前 2 个像素内,对吗?
  • 其实,我要把这个猜测作为答案

标签: c++ image-processing signal-processing


【解决方案1】:

您的上述算法是正确的,但有轻微的空洞。

当您用 0 填充图像时,这些零实际上用于卷积。在 FFT 空间中,这将在图像边缘周围添加巨大的高频分量。在非 FFT 空间中,这意味着边缘上的内核大小最多为 1,0 会被滚入,这会给你在边缘上看起来很奇怪的结果。人们通常以两种方式处理此问题:

  1. 卷积后只需在图像周围丢掉 1 个内核大小的边框。
  2. 将边缘镜像到焊盘中,而不是用零填充它。

为了获得最佳效果,我通常会同时执行 1 和 2(以获得实际图像并消除傅立叶空间中的高频边缘)。

【讨论】:

  • 感谢您的回复。如果您注意到上面我没有填充图像,但我将内核填充到图像的大小
  • @gosum 啊,那么你的问题的根源你也需要填充图像。简而言之,考虑在图像的左上角进行卷积。您的内核只会重叠 4/9 像素。剩下的 9 个像素从哪里获得?简而言之,它不会,并且当这种情况发生时,上述算法会产生无意义的数据(可预测但无用)输出。
  • 所以我需要使用您提出的第二种方法将图像填充为 W+2*M, H+2*M。当我填充内核时,我设置了零?
  • @gosom 是的。图像实际上只需要填充一半的窗口大小(再次,想想左上角,你只需要 3/2=1 行来重叠所有 9 个像素)所以图像和内核最终都是 W+M -1,H+M-1。应该注意的是,这最多只能让您捏造边角,因此如果您对图像进行任何进一步的分析,无论如何您应该丢弃边缘。如果数据的维度是 2 的幂,大多数 FFT 实现会更快。
猜你喜欢
  • 1970-01-01
  • 2011-12-07
  • 2014-07-06
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
相关资源
最近更新 更多