使用可分离属性通过一维卷积进行二维卷积

时间:2013-09-02 10:00:23

标签: matlab image-processing convolution

我正在编写一个程序,我正在进行大量的2D卷积。所以我认为更有效的方法可能是使用一维卷积。但我似乎坚持这一点。

直到现在,我已经提到了这个链接:

检查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,所以它确实是一个可分离的向量,可以表示为两个1 D向量的外积。这里的1D矢量被称为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.

你们可以看到,第一种方法是最快的,而第三种方法也很快。第三个&第二种方法也以e-14的顺序具有非常低的误差,但与使用conv2的第一种方法相比,这两种方法都非常慢。

你能告诉我为什么涉及一维卷积的方法最慢?

提前感谢你们所有人!!

编辑:请参阅我的第四种方法!!

1 个答案:

答案 0 :(得分:0)

第二种方法的结果不是KI1*KI2,而是KI2。请注意,KI2已经被卷入两次。如果使用第二种方法计算KI- KI2,则会出现一个小错误。

关于速度,我有这些评论:

  • 第二种方法中的行KI - KI2和第三种方法中的行KI - KI3正在减慢速度,不应包含在比较中。只需删除它们。
  • 在方法二中,重用变量KI1而不是定义新的KI2:即KI2 = imfilter(KI1,K2,'conv');替换KI1 = imfilter(KI1,K2,'conv');。这可能会减少内存分配所花费的时间。
  • 您的Img矩阵非常小。对于较大的矩阵,第二种方法是最快的。

使用4000次Img矩阵,并应用其他更改,我分别得到:

Elapsed time is 4.924468 seconds.
Elapsed time is 0.793251 seconds.
Elapsed time is 0.854416 seconds.
相关问题