%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%Dr. JuCheng Yang,%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%Division of Electronics & Information Engineering,%%%%%%
%%%Chonbuk National University,%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%664-14 1Ga Deonjin-dong Deonjin-gu,%%%%%%%%%%%%%%%%%%%%%
%%%Jeonju, Jeonbuk, 561-756, Korea.%%%%%%%%%%%%%%%%%%%%%%%%
%%%Email: biometricscode@gmail.com %%%%%%%%%%%%%%%%%%%%%%%%
%%%http://yangjucheng.chonbuk.ac.kr/%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Abstract
%A novel texture-based Automatic Fingerprint Authentication System (AFAS) is proposed. A fingerprint image 
%is preprocessed to enhance the image by Short Time Fourier Transform (STFT) analysis. Then, a set of invariant
%moment features, as a kind of texture features, are extracted from a Region of Interest (ROI) area based on the
%reference point from the enhanced fingerprint image. Each set of invariant moments contain seven invariant moments.
%Fingerprint verification is realized by Euclidean distance between the two corresponding features of the test 
%fingerprint image and template fingerprint image in the database. 

%Reference
%[1] Sharat C., Alexander N. C. Venu G., Fingerprint enhancement using STFT analysis, Pattern Recognition, In Press,
%Corrected Proof, Available online 22 August 2006.
%[2] Kenneth N. and Josef B., Localization of corresponding points in fingerprints by complex filtering, Pattern 
%Recognition Letters, 24, pp2135-2144, 2003. 
%[3] Ju Cheng Yang, Sook Yoon, Dong Sun Park, ¡°Applying Learning Vector Quantization Neural Network for
%Fingerprint Matching¡±, Lecture Notes in Artificial Intelligence (LNAI 4304), Springer, Berlin, Dec., 2006. (SCI ) 
%[4]Ju Cheng Yang, Dong Sun Park, ¡°A Fingerprint Verification Algorithm Using Tessellated Invariant Moment Features¡±,
%Neurocomputing, Vol. 71(10-12) pp. 1939-1946, 2008.(SCI ) 

%Acknowledgement
%The author would like to thank some code suppliers such as Chikkerur Sharat and Luigi ROSA for their contributions.

%Using Guide:
%matlab 6.5 version (or over version)+ image proceesing tools;

%The 1st step, change the files directory as the matlab current directory;
%The 2nd step, in the "command" window, input "test", then "Enter";
%The 3rd step, GUI will be shown.

%"readme.txt" file: 
%this is the introduce file for the algorithm;
%if you want more information, see the website 
%http://yangjucheng.chonbuk.ac.kr/

clear;
clc;
close all;

% 1--> add database
% 0--> recognition
%ok=0;
chos=0;
possibility=5;

messaggio='Insert the number of set: each set determins a class. This set should include a number of images for each person, with some variations in expression and in the lighting.';

while chos~=possibility,
    chos=menu('Fingerprint Authentication System','Select image and add to database','Select image for fingerprint authentication','Delete database',...
        'Fingerprint image: visualization','Exit');
    %--------------------------------------------------------------------------
    %--------------------------------------------------------------------------
    %--------------------------------------------------------------------------
    % Calculate FingerCode and Add to Database
    if chos==1
        clc;
        close all;
        selezionato=0;
        while selezionato==0
            [namefile,pathname]=uigetfile({'*.bmp;*.tif;*.tiff;*.jpg;*.jpeg;*.gif','IMAGE Files (*.bmp,*.tif,*.tiff,*.jpg,*.jpeg,*.gif)'},'Chose GrayScale Image');
            if namefile~=0
                [img,map]=imread(strcat(pathname,namefile));
                selezionato=1;
            else
                disp('Select a grayscale image');
            end
            if (any(namefile~=0) && (~isgray(img)))
                disp('Select a grayscale image');
                selezionato=0;
            end
        end
        
        immagine=double(img);
        
        if isa(img,'uint8')
            graylevmax=2^8-1;
        end
        if isa(img,'uint16')
            graylevmax=2^16-1;
        end
        if isa(img,'uint32')
            graylevmax=2^32-1;
        end
               
        [oimg,fimg,bwimg,eimg,enhimg] =  fft_enhance_cubs(immagine); 
        fingerprint = enhimg;       
        
        %N=h_lato;
        [BinarizedPrint,XofCenter,YofCenter]=centralizing(fingerprint,0);
        [CroppedPrint]=cropping_64(XofCenter,YofCenter,fingerprint);
        %[NormalizedPrint,vector]=sector_norm(CroppedPrint,0);
        
        finger_code_inv=invmoments(CroppedPrint);         
       
        % FingerCode added to database
        if (exist('fp_database.dat')==2)
            load('fp_database.dat','-mat');
            fp_number=fp_number+1; 
            data{fp_number}=finger_code_inv;
            save('fp_database.dat','data','fp_number','-append');
        else
            fp_number=1;  
            data{fp_number}=finger_code_inv;
            save('fp_database.dat','data','fp_number');
        end
        
        message=strcat('FingerCode was succesfully added to database. Fingerprint no. ',num2str(fp_number));
        msgbox(message,'FingerCode DataBase','help');
    end
    %--------------------------------------------------------------------------
    %--------------------------------------------------------------------------
    %--------------------------------------------------------------------------
    % Fingerprint recognition
    if chos==2
        clc;
        close all;
        selezionato=0;
        while selezionato==0
            [namefile,pathname]=uigetfile({'*.bmp;*.tif;*.tiff;*.jpg;*.jpeg;*.gif','IMAGE Files (*.bmp,*.tif,*.tiff,*.jpg,*.jpeg,*.gif)'},'Chose GrayScale Image');
            if namefile~=0
                [img,map]=imread(strcat(pathname,namefile));
                selezionato=1;
            else
                disp('Select a grayscale image');
            end
            if (any(namefile~=0) && (~isgray(img)))
                disp('Select a grayscale image');
                selezionato=0;
            end
        end
        
        immagine=double(img);
        
        if isa(img,'uint8')
            graylevmax=2^8-1;
        end
        if isa(img,'uint16')
            graylevmax=2^16-1;
        end
        if isa(img,'uint32')
            graylevmax=2^32-1;
        end
        
        [oimg,fimg,bwimg,eimg,enhimg] =  fft_enhance_cubs(immagine); 
        
        fingerprint = enhimg;   
        
        %N=h_lato;
        
        [BinarizedPrint,XofCenter,YofCenter]=centralizing(fingerprint,0);
        [CroppedPrint]=cropping_64(XofCenter,YofCenter,fingerprint);
        %[NormalizedPrint,vector]=sector_norm(CroppedPrint,0);
        
        %input vector
        vettore_in=invmoments(CroppedPrint);         
        
        % FingerCode of input fingerprint has just been calculated.
        % Checking with DataBase
        if (exist('fp_database.dat')==2)
            load('fp_database.dat','-mat');
            %---- alloco memoria -----------------------------------
            %template vector
            Vector_Lenth=7;
            vettore_tem=zeros(Vector_Lenth,1);            
            best_matching=zeros(fp_number,1);
            %valori_rotazione=zeros(n_arcs,1);
            % start checking ---------------------------------------
            for scanning=1:fp_number
                fcode1=data{scanning};                 
                vettore_tem=fcode1;  
                %NORM(X) is the largest singular value of X, max(svd(X)).
                d1=norm(vettore_tem-vettore_in);                
                val_minimo=d1;                
                best_matching(scanning)=val_minimo;
            end
            %[Y,I] = MIN(X) returns the indices of the minimum values in vector I.
            [distanza_minima,posizione_minimo]=min(best_matching);
            beep;
            message=strcat('The nearest fingerprint present in DataBase which matchs input fingerprint is  : ',num2str(posizione_minimo),...
                ' with a distance of : ',num2str(distanza_minima));
            msgbox(message,'DataBase Info','help');
            
        else
            message='DataBase is empty. No check is possible.';
            msgbox(message,'FingerCode DataBase Error','warn');    
        end
        
    end % fine caso 2    
    if chos==3
        clc;
        close all;
        if (exist('fp_database.dat')==2)
            button = questdlg('Do you really want to remove the Database?');
            if strcmp(button,'Yes')
                delete('fp_database.dat');
                msgbox('Database was succesfully removed from the current directory.','Database removed','help');
            end
        else
            warndlg('Database is empty.',' Warning ')
        end
    end % fine caso 3
    if chos==4
        clc;
        close all;
        selezionato=0;
        while selezionato==0
            [namefile,pathname]=uigetfile({'*.bmp;*.tif;*.tiff;*.jpg;*.jpeg;*.gif','IMAGE Files (*.bmp,*.tif,*.tiff,*.jpg,*.jpeg,*.gif)'},'Chose GrayScale Image');
            if namefile~=0
                [img,map]=imread(strcat(pathname,namefile));
                selezionato=1;
            else
                disp('Select a grayscale image');
            end
            if (any(namefile~=0) && (~isgray(img)))
                disp('Select a grayscale image');
                selezionato=0;
            end
        end
        figure('Name','Selected image');
        imshow(img);
    end % fine caso 4   
end % fine while