【问题标题】:Seperable convolution using 1D FFT vs 2D FFT使用 1D FFT 与 2D FFT 的可分离卷积
【发布时间】:2014-05-18 23:55:40
【问题描述】:

我正在尝试使用 MATLAB 使用两种方法将图像与高斯滤波器进行卷积:使用 1D FFT 的可分离卷积和使用 2D FFT 的不可分离卷积。我期待可分离卷积更快。但是,它不是用于小图像,而是用于 2D 速度更快的较大图像。我不确定这是否是我的实现有问题,或者是因为我的概念不太正确。

这是我的代码:

img1 = randi([1,256],128,128);    

% Create a Gaassian filter
rf1 = fspecial('gaussian', [1 128], 1.0);
cf1 = transpose(rf1);
gf1 = cf1 * rf1;    

rc1 = round(conv2(img1, gf1, 'same'));
rc1 = fft2dconv(img1, gf1);
rc2 = fft1dconv(img1, rf1, cf1);


function o = fft1dconv(img, rowf, colf)

% Zero-Pad
imgsize = size(img);
rsize = size(rowf);
csize = size(colf);

img = padarray(img, [imgsize(1)/2, imgsize(2)/2]);
rowf = padarray(rowf, [2*imgsize(1)-rsize(1), 2*imgsize(2)-rsize(2)], 'post');
colf = padarray(colf, [2*imgsize(1)-csize(1), 2*imgsize(2)-csize(2)], 'post');


% Seperable convolution using 1D FFT
tic;
result = fft(transpose(fft(img))) .* fft(transpose(fft(colf)));
result = result .* fft(transpose(fft(rowf)));
o = transpose(round(real(ifft2(result))));
toc;


% Remove Pad
o = o(imgsize(1)+1:2*imgsize(1),imgsize(2)+1:2*imgsize(2));

end


function o = fft2dconv(img, filter)

%zero-pad
imgsize = size(img);
fsize = size(filter);

img = padarray(img, [imgsize(1)/2, imgsize(2)/2]);
filter = padarray(filter, [2*imgsize(1)-fsize(1), 2*imgsize(2)-fsize(2)], 'post');

% Non-Seperable convolution using 2D FFT
tic;
o = round(real(ifft2(fft2(img) .* fft2(filter))));
toc;

% Remove Pad
o = o(imgsize(1)+1:2*imgsize(1),imgsize(2)+1:2*imgsize(2));

end

而计时结果分别是:

Elapsed time is 0.003315 seconds.
Elapsed time is 0.004369 seconds.

对于 4 x 4 图像,可分离方法要快得多,但对于较大的图像。事实并非如此,我不知道为什么。任何帮助将非常感激。

【问题讨论】:

  • 只是一些猜测。 (我没有足够的知识来验证这些说法。)MATLAB 的fft2 还执行可分离性检查(实际上,也执行 SVD 低秩近似)。在内部,fft2 使用 ATLAS 或 FFTW,这两种都被认为是商业上最快的 FFT 实现。 (一些旧版本使用 IPP。)最后,MATLAB 内部使用的 C 实现(与 ATLAS 和 FFTW 交互时)不需要执行转置 - 它只是“告诉”底层库以转置方式读取数组.

标签: matlab image-processing signal-processing fft convolution


【解决方案1】:

我建议你 profile 你的代码看看发生了什么。可能是您正在执行的其他一些操作,而不是核心 FFT 计算本身。

进入 MATLAB 并输入profile viewer。一旦你这样做了,在那个窗口中运行你的命令并让它完成。完成后,它将识别代码的密集部分,您可以从那里找出如何优化它。你说得对,可分离过滤器更快。

【讨论】:

  • @user115188 哇!来自过去的幽灵!你最终弄清楚为什么时间不对了吗?
猜你喜欢
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
相关资源
最近更新 更多