According to this Quora answer, Gabor filter is a frequency domain filter. And, here is an implementation of Gabor filter which uses imfilter()
to achieve the filtering, which means that
imfilter()
works in the frequency domain.
Now, let us look at Source Code #1.
If I replace
I_ffted_shifted_filtered = I_ffted_shifted.*Kernel;
with
I_filtered = imfilter(I, Kernel);
as the following
function [out1, out2] = butterworth_lpf_imfilter(I, Dl, n)
Kernel = butter_lp_kernel(I, Dl, n);
I_filtered = imfilter(I, Kernel);
out1 = ifftshow(ifft2(I_filtered));
out2 = ifft2(ifftshift(I_filtered));
end
we don't obtain the expected output,
Why doesn't this work? What is the problem in my code?
Source Code #1
main.m
clear_all();
I = gray_imread('cameraman.png');
Dl = 10;
n = 1;
[J, K] = butterworth_lpf(I, Dl, n);
imshowpair(I, J, 'montage');
butterworth_lpf.m
function [out1, out2] = butterworth_lpf(I, Dl, n)
Kernel = butter_lp_kernel(I, Dl, n);
I_ffted_shifted = fftshift(fft2(I));
I_ffted_shifted_filtered = I_ffted_shifted.*Kernel;
out1 = ifftshow(ifft2(I_ffted_shifted_filtered));
out2 = ifft2(ifftshift(I_ffted_shifted_filtered));
end
butter_lp_kernel.m
function k = butter_lp_kernel(I, Dl, n)
Height = size(I,1);
Width = size(I,2);
[u, v] = meshgrid( ...
-floor(Width/2) :floor(Width-1)/2, ...
-floor(Height/2): floor(Height-1)/2 ...
);
k = butter_lp_f(u, v, Dl, n);
function f = butter_lp_f(u, v, Dl, n)
uv = u.^2+v.^2;
Duv = sqrt(uv);
frac = Duv./Dl;
denom = frac.^(2*n);
f = 1./(1.+denom);
Output
imfilter takes a spatial domain representation of an image A and a spatial domain kernel h, and returns a spatial domain image, B. Whatever domain or algorithm is used to compute B is an implementation detail. That said, imfilter uses spatial convolution to compute B.
As you can see in the comments above, a Gabor filter is not a "frequency domain filter". A Gabor filter is LTI and as such the filtering operation can be implemented in either domain. This should make sense, given that the "gaussian modulated with a sinusoid" waveforms that are frequently shown in the literature when discussing Gabor filter banks are in the spatial domain.
It happens that in the spatial domain, Gabor filter kernels can get large and are non-separable in the general case unless theta is a multiple of 90 degrees unless you want to use approximate techniques. So, it is common to use a frequency domain implementation of Gabor filtering for speed purposes. This is what imgaborfilt does in IPT.
If you have IPT, I recommend looking at the code in gabor and imgaborfilt for more information.
https://www.mathworks.com/help/images/ref/imgaborfilt.html
https://www.mathworks.com/help/images/ref/gabor.html
In the implementation you are using, they are using a frequency domain implementation. If you want to use imfilter, you would have to pass in the equivalent spatial domain representation of the Gabor filter. It does not make sense to pass a frequency domain representation of the Gabor filter to imfilter as you are currently doing. That is not a Gabor filtering operation.