可分离卷积没有加速

No speed up in Separable Convolution

我正在实施可分离卷积以加速 2D 高斯卷积。

clear all;
close all;

im = randi([0,255],1024,1024);

win = 7;
window = fspecial('gaussian',win,win/6);

[U, S, V] = svd(window);
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));

out1 = filter2(window, im);
out2 = filter2(h, filter2(v, im));
norm(out1 - out2)

tic
for i = 1:1000
    out1 = filter2(window, im);
end
toc

tic
for i = 1:1000
    out2 = filter2(h, filter2(v, im));
end
toc

分离版应该快win*win/(win + win) = 2.5倍,但实际上更慢:

ans =
2.6250e-12

Elapsed time is 5.486270 seconds.
Elapsed time is 8.769868 seconds.

filter2里面有没有隐藏的实现?

首先,如果您查看 filter2 的源代码,您会发现它已经使用相同的可分离 SVD 方法实现。这是 filter2 在你的案例中所做的要点(但你真的应该单步执行代码):

[U, S, V] = svd(window,'econ');
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));
out2 = conv2(v, h, im, 'same');

你做的是一样的,但不是使用更有效的单一调用 conv2(v, h, im, 'same'),你最终会进行递归调用 conv2(conv2(im, v, 'same'), h, 'same'),这显然是它变慢的原因。

Matlab 对内置 conv 函数集(包括 conv2)的实现不是最优的。您可以在此处阅读有关它(和解决方法)的信息:http://undocumentedmatlab.com/blog/convolution-performance

基本思想是使用卷积定理或基于 C++ 的 MEX 实现,或者最好同时使用两者,如 Bruno Luong 所使用的 convfft实用程序。