私は多くの 2D 畳み込みを行っているプログラムを書いています。したがって、より効率的なアプローチは、1D畳み込みを使用することであると考えました。しかし、私はこれにこだわっているようです。
今まで、私はこのリンクを参照してきました:
これをチェックしてください 1) http://blogs.mathworks.com/steve/2006/10/04/separable-convolution/
これを確認してください 2) http://blogs.mathworks.com/steve/2006/11/28/separable-convolution-part-2/
サイズ 5X5 のガウス カーネル (K) があります。このカーネル関数と画像を畳み込む必要があります。私の画像サイズは 4000X4000 に強制されています。以下にプログラムを示します。
clc;clear all;close all;
imgID = 5;
Img = imread([num2str(imgID),'.bmp']);
Img = double(Img(:,:,1));
Img = imresize(Img,[4000 4000]);
sigma=3.0;
K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % the Gaussian kernel
%%
%//Trying to use 1D convolution instead of using 2D convolution
[U,S,V] = svd(K);
K1 = U(:,1) * sqrt(S(1,1));
K2 = V(:,1)' * sqrt(S(1,1));
%%
tic
KI=conv2(Img,K,'same');
toc
tic
KI1 = imfilter(Img,K1,'conv');
KI1 = imfilter(KI1,K2,'conv');
toc
tic
KI2 = imfilter(Img,K,'conv');
toc
tic
KI3 = conv2(K1,K2,Img,'same');
toc
行列 K のランクを確認しました。1 になるので、2 つの 1D ベクトルの外積として表現できる分離可能なベクトルです。ここでの 1 次元ベクトルは、K1 および K2 と呼ばれます。次に、どちらの方法が速いかを知るために時間を計りましたか? 結果を以下に示します。
%//1st method
Elapsed time is 0.375002 seconds.
%//2nd method
Elapsed time is 1.601285 seconds.
%//3rd method
Elapsed time is 1.884165 seconds.
%//4th method
Elapsed time is 0.315134 seconds.
ご覧のとおり、最初の方法が最も高速ですが、3 番目の方法も非常に高速です。3番目と2番目の方法もe-14のオーダーで非常に低いエラーですが、これらの方法はどちらもconv2を使用する最初の方法と比較して非常に遅いです.
1D畳み込みを含む方法が最も遅い理由を教えてください。
皆さん、よろしくお願いします!!
編集:私の4番目の方法を見てください!!