在C中实现2D卷积的快速方法

时间:2009-03-24 09:46:22

标签: c image filter 2d

我正在尝试实现视觉算法,其中包括具有9x9拉普拉斯高斯滤波器的预滤波阶段。您能指出一个简要解释快速过滤器实现的文档吗?我想我应该利用FFT进行最有效的过滤。

3 个答案:

答案 0 :(得分:10)

您确定要使用FFT吗?这将是一个全数组转换,这将是昂贵的。如果您已经决定使用9x9卷积滤波器,则不需要任何FFT。

通常,在C中进行卷积的最便宜方法是设置一个循环,将指针移到数组上,对每个点处的卷积值求和并将数据写入新数组。然后可以使用您喜欢的方法(编译器矢量化,MPI库,OpenMP等)并行化此循环。

关于边界:

  • 如果假设边界外的值为0,则在2d点数组中添加0元素边界0。这将避免需要`if`语句来处理边界,这是很昂贵的。
  • 如果您的数据在边界处包裹(即它是周期性的),则使用模数或添加4个元素边框,复制网格的另一侧(abcdefg - > fgabcdefgab为2个点)。 **注意:这是你用任何类型的傅立叶变换隐含的假设,包括FFT **。如果不是这种情况,则需要在完成任何FFT之前对其进行说明。

4个点是因为9x9内核的最大边界重叠是主网格外的4个点。因此,2n + 1 x 2n + 1内核需要n个边界点。

如果你需要这个卷积非常快,和/或你的网格很大,可以考虑将它分成可以保存在处理器缓存中的较小部分,从而更快地计算出来。这也适用于您可能想要进行的任何GPU卸载(它们非常适合此类浮点计算)。

答案 1 :(得分:2)

这是一个理论联系 http://hebb.mit.edu/courses/9.29/2002/readings/c13-1.pdf

这里有一个指向fftw的链接,这是我过去使用的一个非常好的FFT库(检查许可证以确保它是合适的)http://www.fftw.org/

您所做的就是对图像和内核进行FFT(9x9矩阵)。乘以一起,然后再变换。

然而,使用9x9矩阵,你可能仍然可以在真实坐标中做得更好(只需在图像像素和矩阵上进行双循环)。尝试两种方式!

答案 2 :(得分:1)

实际上,您不需要使用足够大的FFT大小来容纳整个图像。你可以做很多较小的重叠2d fft。您可以搜索“快速卷积”“重叠保存”“重叠添加”。

然而,对于9x9内核。你可能没有看到很多优势。