# Performance of MATLAB's conv2() vs. imfilter()

A lot of people use imfilter to achieve a 2-D convolution between an image and a filter, but the majority of people use conv2 instead of imfilter because it is faster than imfilter by at least 20%.

Examples:

filtered_image_with_imfilter = imfilter(image,filter,'symmetric','same','corr');
filtered_image_with_conv2 = conv2(image,filter,'same');


Could someone explain to me in detail why conv2 is faster than imfilter.

First, I think conv2 and imfilter will give you the same result if you change the filter option of imfilter to conv instead of corr. imfilter uses correlation to filter images by default that starts from one side of the image, whereas covolution starts from the other, so there may be some small differences in the filter output.

Secondly, my test shows imfilter on 2D image is faster if the filter size if the same as images.

clc
data = (rand(200));
kernel = ones(200)/4e4;
tic
blurredData = conv2(data, kernel,'same');
conv2t=toc
tic
blurredData = imfilter(data, kernel,'same','conv');
imfiltime=toc

>> conv2t =

2.7425

imfiltime =

0.1552


Both imfilter and conv2 are hardware optimized and multi-threaded. For floating point inputs, the performance of them are supposed to be roughly the same. But in most cases in image processing, the filter kernel is linearly separable, imfilter does separation of the kernel into row and column vectors. As a result, they are much faster. Yet if the filter kernel is (1) not linearly separable, or (2) a small kernel such as a 5*5 filter kernel. conv2 wins in the processing time. I guess the reason is some time is spent on checking the separability of the kernel in imfilter. I am not sure whether there are other different mechanisms that leads to the processing time difference between the two.

Finally, if the filter size is the same as image. fft is always the best one (O(nlogn)):

clc
data = (rand(200));
kernel = ones(200)/4e4;
tic
blurredData = conv2(data, kernel,'same');
conv2t=toc
tic
blurredData = imfilter(data, kernel,'same','conv');
imfiltime=toc
tic
D=fft2(data);
K=fft2(kernel);
blurdata=ifft2(D.*K);
fftime=toc

>>conv2t =

2.7429

imfiltime =

0.1327

fftime =

0.0164


EDIT

@geometrikal's detailed analysis: The reason fft is faster than imfilter with same size images is that imfilter pads the inputs (even with 'same'). For small filter kernels, not much padding is needed for imfilter, whereas to use the fft the kernel will have to be padded to the size of the image. In these cases imfilter is faster.

• Firstly, thank you very much for your answer!. By using other than floating points like as grayscale images, your explanation remains the same ? In other words, instead of data=rand(200), the data can be a grayscale image – Christina Jan 1 '14 at 22:54
• For integer input images (0-255 for example), imfilter has integer optimized code paths, so it is expected at least not much slower than conv2 I think. Yet fft2 is always the fastest – lennon310 Jan 1 '14 at 23:00
• I appreciate very much your opinion. Thank you again Dear. – Christina Jan 1 '14 at 23:09
• The reason fft is faster than imfilter with same size images is that imfilter pads the inputs (even with 'same'). For small filter kernels, not much padding is needed for imfilter, whereas to use the fft the kernel will have to be padded to the size of the image. In these cases imfilter is faster. – geometrikal Jan 2 '14 at 6:25
• @geometrikal thank you for your response :) it is interested :) – Christina Jan 2 '14 at 10:00

For the 1-d case, I think that conv() is implemented in the direct domain while xcorr is implemented in the frequency domain.

This indicates that conv will be faster for small kernels, while xcorr will be faster when inputs are equal size.

I dont know if this still is the case, and if it extends to the 2-d case.

Operations that allows for native single-precision can be up to 2x faster by casting input from double to single (eg the fft). In some cases, even though the function use the fft for heavy lifting, it does not allow for end-to-end single precision.

By considering the column-major nature of Matlab it is sometimes possible to realize large speedups (4x or more) by carefully laying out operations in memory such that large jumps and scatter/gather is not needed.

• Thank you for your answer:) – Christina Mar 30 at 9:54