我一直在使用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中获得最佳性能。
更多有用的链接:
- 傅立叶变换
- 卷积和滤波
免责声明:
- ArrayFire不是开源的。然而,它有一个免费使用的版本
- 我在AccelerateEyes工作,并开发arrayfire。我之所以链接到我们的产品,是因为@solvingPuzzles特别要求提供一个类似于arrayfire的库