function [obr_fil] = geometricky2D(X,P,obr)

%% **********************************************************************************
%*  Kamil Sokol		
%*	Geometrická filtrácia 2D s voliteľnou veľkosťou masky
%*  X       - veľkosť masky (1,2,3,4...) [ (2*X+1) x (2*X+1)]
%*  P       - počet iterácii
%*  obr     - vstupný obrázok pre filtráciu
%*  obr_fil - výstupný obrázok - filtrovaný
%************************************************************************************

%% Funkcia **************************************************************************
tStart=tic;                 %štart merania času výpočtu 
[m,n] = size (obr);         %zistenie rozmerov org. obrazu
obr_fil = zeros(m,n);       %vytvorenie prázdnej matice pre výsledny obr.
obr_zvacseny = zeros((m+2*X),(n+2*X));  %vytvorenie prázdnej matice pre zvacseny obr.

fprintf('Geometrická filtrácia 2D: START\n');    %Vypisanie informacie
fprintf('Geometrická filtrácia 2D hotova z:  00.00 %%');
%************************************************************************************
%% Filtrácia ************************************************************************
for p = 1:1:P                               %opakovanie podla poctu iteracii
    
    [obr_zvacseny] = zvacsenie (obr,X);     %volanie funkcie pre zvacsenie
    
    % Filtrácia 1 (|)
    for i = 1:1:(m)                         %Pohyb okna v 2 osách
        for j = 1:1:(n)
                A = obr_zvacseny(i,j+X);    %výber bodov A, B, C pre porovnanie   
                B = obr_zvacseny(i+X,j+X);
                C = obr_zvacseny(i+2*X,j+X);
                [Y] = geo_vypocet(A,B,C);   %Volanie funkcie pre porvnavania
                obr_fil(i,j) = Y;           %Zapísanie výsledku   
        end
    end
    
    [obr_zvacseny] = zvacsenie (obr_fil,X);
    
    % Filtrácia 2 (-)
    for i = 1:1:(m)
        for j = 1:1:(n)
                A = obr_zvacseny(i+X,j);       
                B = obr_zvacseny(i+X,j+X);
                C = obr_zvacseny(i+X,j+2*X);
                [Y] = geo_vypocet(A,B,C);
                obr_fil(i,j) = Y;              
        end
    end    

    [obr_zvacseny] = zvacsenie (obr_fil,X);
    
    % Filtrácia 3 (\)
    for i = 1:1:(m)
        for j = 1:1:(n)
                A = obr_zvacseny(i,j);       
                B = obr_zvacseny(i+X,j+X);
                C = obr_zvacseny(i+2*X,j+2*X);
                [Y] = geo_vypocet(A,B,C);
                obr_fil(i,j) = Y;              
        end
    end
    
    [obr_zvacseny] = zvacsenie (obr_fil,X);
    
    % Filtrácia 4 (/)
    for i = 1:1:(m)
        for j = 1:1:(n)
                A = obr_zvacseny(i+2*X,j);       
                B = obr_zvacseny(i+X,j+X);
                C = obr_zvacseny(i,j+2*X);
                [Y] = geo_vypocet(A,B,C);
                obr_fil(i,j) = Y;              
        end
    end
 
    obr(:,:) = obr_fil(:,:);
    progres = (p/P)*100;   %výpočet progresu
    fprintf('\b\b\b\b\b\b\b%05.2f %%',progres);    
end

max_value = max(max(obr_fil));
obr_fil = obr_fil./max_value;         %uprava rozmedzia jasu
tElapsed=toc(tStart);                 %koniec merania času výpočtu
fprintf('\nGeometrická filtrácia 2D vypočítaná za: %.1f sekúnd \nGeometrická filtrácia 2D: HOTOVO \n\n',tElapsed);

end

%% Výpočet **************************************************************************
function [y] = geo_vypocet(a,b,c)
d = 0;              %funkcia pre porvnavanie jednotlivych bodov    
if (b <= a-2)            
    d = 1;        
end

if (b <= c-2)            
    d = 1;        
end

if (b < a && b <= c)            
    d = 1;        
end

if (b < c && b <= a)            
    d = 1;        
end

if (b >= a-2)            
    d = 2;
end

if (b >= c-2)            
    d = 2;        
end

if (b > a && b >= c)            
    d = 2;        
end

if (b > c && b >= a)            
    d = 2;        
end
                %uprava výsledneho jasu pre dany bod
switch d
    case 0                
        y = b;
    case 1                
        y = b + 1;                        
    case 2                
        y = b - 1;        
end

if y<0               
    y = 0;                
end
                %uprava jasu, aby neprekročila hranice
if y > 255
    y = 255;    
end

end
%************************************************************************************
function [obr_zvacseny] = zvacsenie (obr,X)
[m,n] = size (obr);
obr_zvacseny((1+X):(m+X),(1+X):(n+X)) = obr(:,:);    %vlozenie obr, do stredu zvacsenej matice
for i = 1:1:(X)        
    obr_zvacseny(i,:) = obr_zvacseny(1+X,:);         %zvecsenie <-m        
    obr_zvacseny(X+m+i,:) = obr_zvacseny(X+m,:);     %zvecsenie m->        
    obr_zvacseny(:,i) = obr_zvacseny(:,1+X);         %zvecsenie <-n        
    obr_zvacseny(:,X+n+i) = obr_zvacseny(:,X+n);     %zvecsenie n->    
end
end
%************************************************************************************