matlabimage-processinggabor-filter

How does the Gabor filter work?


I have found a good Gabor Filter source code from this link. The code is very clean and well-documented.

My question is here,

for i = 1:u    
    ...............
    ...............
    ...............        
    for j = 1:v
        tetav = ((j-1)/v)*pi;
        .....................            
        for x = 1:m
            for y = 1:n
                xprime = ........
                yprime = ........
                gFilter(x,y) = ........
            end
        end
        gaborArray{i,j} = gFilter;        
    end
end

What does it mean by tetav = ((j-1)/v)*pi;? Is it radian or degree? If it is radian, why wasn't it divided by 180?

Why does the kernel computation go from 1 to m or n? Why not from -(m/2) to (m+1)/2?


Source Code

gaborFeatures.m

function gaborResult = gaborFeatures(img,gaborArray,d1,d2)

if (nargin ~= 4)        % Check correct number of arguments
    error('Please use the correct number of input arguments!')
end

if size(img,3) == 3     % Check if the input image is grayscale
    warning('The input RGB image is converted to grayscale!')
    img = rgb2gray(img);
end

img = double(img);


% Filter input image by each Gabor filter
[u,v] = size(gaborArray);
gaborResult = cell(u,v);
for i = 1:u
    for j = 1:v
        gaborResult{i,j} = imfilter(img, gaborArray{i,j});
    end
end

gaborFilterBank.m

function gaborArray = gaborFilterBank(u,v,m,n)    
if (nargin ~= 4)    % Check correct number of arguments
    error('There must be four input arguments (Number of scales and orientations and the 2-D size of the filter)!')
end 

% Create u*v gabor filters each being an m by n matrix 
gaborArray = cell(u,v);
fmax = 0.25;
gama = sqrt(2);
eta = sqrt(2);

for i = 1:u

    fu = fmax/((sqrt(2))^(i-1));
    alpha = fu/gama;
    beta = fu/eta;

    for j = 1:v
        tetav = ((j-1)/v)*pi;
        gFilter = zeros(m,n);

        for x = 1:m
            for y = 1:n
                xprime = (x-((m+1)/2))*cos(tetav)+(y-((n+1)/2))*sin(tetav);
                yprime = -(x-((m+1)/2))*sin(tetav)+(y-((n+1)/2))*cos(tetav);
                gFilter(x,y) = (fu^2/(pi*gama*eta))*exp(-((alpha^2)*(xprime^2)+(beta^2)*(yprime^2)))*exp(1i*2*pi*fu*xprime);
            end
        end
        gaborArray{i,j} = gFilter;        
    end
end

Solution

  • What does it mean by tetav = ((j-1)/v)*pi;?

    This means that tetav will take on increasingly larger pieces of pi; starting with 0 and increasing to the whole thing (i.e. 3.14159...). There are 180 degrees or pi radians in half a circle. So tetav will be taking on increasingly portions of half a circle.

    Is it radian or degree?

    It is radians.

    If it is radian, why wasn't it divided by 180?

    Radians are the desired unit here (for whoever programmed this). They could have instead multiplied by pi if they wanted everything in degrees. If, hypothetically, you were thinking that the expression ((j-1)/v) was in degrees and needed to be converted to radians by a multiplication of pi/180, well that would mean the function would cover, at most, 1 degree of your circle.

    Why does the kernel computation go from 1 to m or n? Why not from -(m/2) to (m+1)/2?

    It is because they chose to instead handle the -(m/2) to (m+1)/2 inside the loop. It is in the code you posted for the gaborFilterBank.m file:

    xprime = (x-((m+1)/2))*cos(tetav)+(y-((n+1)/2))*sin(tetav);
    yprime = -(x-((m+1)/2))*sin(tetav)+(y-((n+1)/2))*cos(tetav);
    

    Since they sin and cosine are being combined, you'll be getting the full circle covered by this Gabor filter. And the offset is adjusted for the x and y center points by the -((m+1)/2) calls. For example, when x = 1 the expression (x-((m+1)/2)) becomes -(m+1)/2+1 or -m/2+0.5 and when x = m, the same expression becomes m/2+0.5, so it is still covering the range you are wondering about.