使用cuFFT实现图像卷积的GPU库



我一直在使用Nvidia Performance Primitives(NPP)的图像卷积函数。然而,我的内核在图像大小方面相当大,我听说NPP的卷积是直接卷积,而不是基于FFT的卷积。(我认为NPP源代码不可用,所以我不确定它是如何实现的。)

我想看看基于cuFFT的卷积函数在我正在开发的图像处理应用程序中运行的速度有多快

你可能会说:"嘿,把你的图像输入到cuFFT中,看看它有多快!"如果我使用的是Matlab,你是对的——这是Matlab:中的一行调用

%assuming the images are padded
convolved = ifft2(fft2(image).* fft2(filter));

然而,需要大量的锅炉板材料来获得cuFFT来进行图像卷积。所以,我正在寻找一个代码,做一个基于cuFFT的卷积和抽象的实现。事实上,我确实发现了一些东西:

  • 这个github repo有一个名为cufft_sample.cu的文件。我认为代码看起来很有希望,但我在repo中发现了另一个文件,其中包含评论,称卷积实现产生了不正确的结果:

WARNING: GpuFFTConvOp currently don't return the good answer
TODO: extend to cover more case, as in many case we will crash!
  • Kitware VTK/ITK代码库提供了基于cuFFT的图像卷积。遗憾的是,事实证明(充其量)做基于cuFFT的例程是为未来的版本计划的。

  • 我在Matlab文件交换上找到了一些做2D卷积的代码。重要的部分是用C/CUDA实现的,但有一个Matlab包装器。我正在剥离Matlab包装器,转而使用纯C/C++/CUDA,但我仍然很好奇是否有更优雅和/或经过验证的解决方案。

这三个选项中有什么建议吗

在进行基于cuFFT的图像卷积的预构建代码方面,还有什么

您可以尝试arrayfire。

在ArrayFire中,您可以执行以下操作。

array image(rows, columns, h_image);
array filter(frows, fcols, h_filter);
array res = convolve(image, filter); 

根据滤波器的大小,conolve命令使用cufft或更快的手动调整内核。如果您更喜欢使用fft2,您可以执行以下

array res = ifft2(fft2(image) * fft2(filter));

但我强烈建议您使用convolve,因为它已经过优化,可以从cufft中获得最佳性能。

更多有用的链接:

  1. 傅立叶变换
  2. 卷积和滤波

免责声明:

  • ArrayFire不是开源的。然而,它有一个免费使用的版本
  • 我在AccelerateEyes工作,并开发arrayfire。我之所以链接到我们的产品,是因为@solvingPuzzles特别要求提供一个类似于arrayfire的库

最新更新