我实现了可分离卷积以加速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中是否有隐藏的实现?
答案 0 :(得分:1)
首先,如果您查看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')
,这显然是使它变慢的原因。
答案 1 :(得分:0)
Matlab对内置conv
函数集(包括conv2
)的实现是次优的。你可以在这里阅读它(和解决方法):http://undocumentedmatlab.com/blog/convolution-performance。
基本思想是使用卷积定理或基于C ++的MEX实现,或者最好使用两者,如Bruno Luong的 convfft < / strong>实用程序。