% -- Načtení, zpracování a identifikace otisku prstu --
% -----------------------------------------------------
%
% Program je součástí diplomové práce - Snímání otisku prstu
% 
% Bc. Michal Kubiš
% Fakulta elektrotechniky a komunikačních technologií na VUT v Brně
% Vedoucí: Ing. Petr Fedra
% 
% 21. 5. 2010


function varargout = START(varargin)


% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @START_OpeningFcn, ...
                   'gui_OutputFcn',  @START_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% Přidání adresářu s jednotlivými funkcemi
addpath(fullfile(pwd,'fcnGabor'));
addpath(fullfile(pwd,'fcnMinutia'));
addpath(fullfile(pwd,'fcnStft'));
addpath(fullfile(pwd,'fcnFft'));
addpath(fullfile(pwd,'data'));



function START_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;

guidata(hObject, handles);




function varargout = START_OutputFcn(hObject, eventdata, handles) 

varargout{1} = handles.output;




function btnFingerprintOpen_Callback(hObject, eventdata, handles)
% --- Otevření obrázku ze souboru a jeho zobrazení

[FileFingerprint, PathName] = uigetfile('*.bmp;*.tif;*.jpg','Otevřít otisk prstu');
handles.fingerprint=imread(FileFingerprint);
axes(handles.axsFingerprint);
imshow(handles.fingerprint);

handles.e = 0;

guidata(hObject, handles);
set(handles.panAxsFingerprint,'Title','Otevřený otisk prstu');
%set(handles.buttonGaborParam,'enable','on')


function btnReadFromReader_Callback(hObject, eventdata, handles)
FingerScan();

function buttonGaborAreaPapilar_Callback(hObject, eventdata, handles)

handles.t = cputime; 

if evalin('base','exist(''BlockSize'')') == 0   % Zjišťuje zda jsou změnené
    assignin('base', 'BlockSize', 16)           % parametry. Pokud ne, použije
    assignin('base', 'Thresold', 0.1)           % výchozí hodnoty
end

BlockSize = evalin('base', 'BlockSize');        % Načte hodnoty z workspace
Thresold = evalin('base', 'Thresold');


% Identifikace oblasti s papilárními liniemi
[handles.normim, handles.mask] = ridgesegment(handles.fingerprint, BlockSize, Thresold);
axes(handles.axsFingerprint); %Výběr plochy pro kreslení
imshow(handles.normim);

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles); % Uložení výsledku jako globální proměná

set(handles.panAxsFingerprint,'Title','Otisk s identifikovaným pozadím a popředím');

%set(handles.buttonRidgeOrient,'enable','on')


function buttonGaborParam_Callback(hObject, eventdata, handles)

GaborParam();
%set(handles.buttonGaborAreaPapilar,'enable','on')


function btnEnd_Callback(hObject, eventdata, handles)
clear all; close all;
close(START);


function buttonRidgeOrient_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''GradientSigma'')') == 0      % Zjišťuje zda jsou změnené
    assignin('base', 'GradientSigma', 1)               % parametry. Pokud ne, použije
    assignin('base', 'BlockSigma', 5)                  % výchozí hodnoty
    assignin('base', 'OrientSmoothSigma',5)
end

GradientSigma = evalin('base', 'GradientSigma');        % Načte hodnoty z workspace
BlockSigma = evalin('base', 'BlockSigma');
OrientSmoothSigma = evalin('base', 'OrientSmoothSigma');

% Odhad orientací papilárních linií
[handles.orientim, handles.reliability] = ridgeorient(handles.normim, GradientSigma, BlockSigma, OrientSmoothSigma);
axes(handles.axsFingerprint);
plotridgeorient(handles.orientim, 20, handles.fingerprint, 2)
set(handles.panAxsFingerprint,'Title','Odhad orientací papilárních linií');

handles.e = handles.e + cputime-handles.t;


guidata(hObject, handles);


%set(handles.buttonRidgeFreq,'enable','on')




function buttonRidgeFreq_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''Blksze'')') == 0     
    assignin('base', 'Blksze', 32)               
    assignin('base', 'Windsze', 5)                  
    assignin('base', 'MinWaveLength',5)
    assignin('base', 'MaxWaveLength',15)
end

Blksze = evalin('base', 'Blksze');        
Windsze = evalin('base', 'Windsze');
MinWaveLength = evalin('base', 'MinWaveLength');
MaxWaveLength = evalin('base', 'MaxWaveLength');

% Odhad frekvencí papilárních linií
[handles.freq, handles.medfreq] = ridgefreq(handles.normim, handles.mask, handles.orientim, Blksze, Windsze, MinWaveLength, MaxWaveLength);
axes(handles.axsFingerprint);
imshow(handles.freq,3)
set(handles.panAxsFingerprint,'Title','Odhad frekvencí papilárních linií');
freq = (handles.medfreq).*(handles.mask);

handles.e = handles.e + cputime-handles.t;


guidata(hObject, handles);

%set(handles.buttonRidgeFilter,'enable','on')


function buttonRidgeFilter_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''Ky'')') == 0     
    assignin('base', 'Kx', 0.5)               
    assignin('base', 'Ky', 0.5)
    assignin('base', 'ReliableParam', 0.4)
end

Kx = evalin('base', 'Kx');
Ky = evalin('base', 'Ky');
ReliableParam = evalin('base', 'ReliableParam');


handles.newim = ridgefilter(handles.normim, handles.orientim, handles.freq, Kx, Ky);
axes(handles.axsFingerprint);
%imshow(handles.newim,4);
%set(handles.panAxsFingerprint,'Title','Otisk prstu po filtraci za pomoci Gaborových filtrů');

handles.binim = handles.newim > 0;

imshow((handles.binim).*(handles.mask).*((handles.reliability)>ReliableParam), 7)
set(handles.panAxsFingerprint,'Title','Otisk prstu po filtraci za pomoci Gaborových filtrů');
imshow(handles.binim);

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.btnThining,'enable','on')


function btnThining_Callback(hObject, eventdata, handles)

handles.t = cputime; 


handles.thinim=im2double(bwmorph((handles.binim),'thin',Inf)); %Ztenčení otisku
axes(handles.axsFingerprint);
imshow(handles.thinim, []);
set(handles.panAxsFingerprint,'Title','Ztenčené hrany papilárních linií');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.btnRemoveSpike,'enable','on')


function btnRemoveSpike_Callback(hObject, eventdata, handles)

handles.t = cputime; 


handles.thinim=im2double(bwmorph(handles.thinim,'clean'));
handles.thinim=im2double(bwmorph(handles.thinim,'hbreak'));
handles.thinim=im2double(bwmorph(handles.thinim,'spur'));

axes(handles.axsFingerprint);
imshow(handles.thinim);

set(handles.panAxsFingerprint,'Title','Odstraněné nepřenosti ve ztenčeném otisku');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.btnMinutaeDirection,'enable','on')



function btnMinutaeDirection_Callback(hObject, eventdata, handles)

handles.t = cputime; 


axes(handles.axsFingerprint);
[handles.o1Bound,handles.o1Area]=direction(handles.thinim,16);

set(handles.panAxsFingerprint,'Title','Orientace papilárních linií pro výpočet markant');


handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.btnMinutiaExtraction,'enable','on')



function btnMinutiaExtraction_Callback(hObject, eventdata, handles)

handles.t = cputime; 


w = 16;
[handles.end_list1,handles.branch_list1,handles.ridgeMap1,handles.edgeWidth]=mark_minutia(handles.thinim,handles.o1Bound,handles.o1Area,w);
axes(handles.axsFingerprint);
show_minutia(handles.thinim,handles.end_list1,handles.branch_list1);
set(handles.panAxsFingerprint,'Title','Všechny zakončovací a rozvětvovací markanty');

handles.e = handles.e + cputime-handles.t;


guidata(hObject, handles);

%set(handles.btnRemFalseMinutia,'enable','on')



function btnRemFalseMinutia_Callback(hObject, eventdata, handles)

handles.t = cputime; 


[handles.pathMap1,handles.real_end1,handles.real_branch1]=remove_spurious_Minutia(handles.thinim,handles.end_list1,handles.branch_list1,handles.o1Area,handles.ridgeMap1,handles.edgeWidth);
axes(handles.axsFingerprint);
show_minutia(handles.thinim,handles.real_end1,handles.real_branch1);
%show_minutia(handles.thinim,handles.real_end1);
set(handles.panAxsFingerprint,'Title','Vybrané zakončovací a rozvětvovací markanty');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);
assignin('base', 'RealEnd1', handles.real_end1)
assignin('base', 'PathMap1', handles.pathMap1)

%set(handles.btnSaveMinutia,'enable','on')



function btnSaveMinutia_Callback(hObject, eventdata, handles)

handles.t = cputime; 


RealEnd1 = evalin('base', 'RealEnd1');
PathMap1 = evalin('base', 'PathMap1');

W=inputdlg('Jméno osoby:');
W=char(W);
save(W,'RealEnd1','PathMap1','-ASCII');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


function btnFingerprintMatch_Callback(hObject, eventdata, handles)

handles.t = cputime; 


finger1=fingerTemplateRead;
finger2=fingerTemplateRead;
percent_match=match_end(finger1,finger2,10)

time_elapsed = handles.e + cputime-handles.t



function pushbutton23_Callback(hObject, eventdata, handles)


function pushbutton24_Callback(hObject, eventdata, handles)


function pushbutton25_Callback(hObject, eventdata, handles)


function pushbutton26_Callback(hObject, eventdata, handles)


function pushbutton27_Callback(hObject, eventdata, handles)


function btnGaborParam_Callback(hObject, eventdata, handles)
GaborParam();


function btnGaborAreaPapilar_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''BlockSize'')') == 0   % Zjišťuje zda jsou změnené
    assignin('base', 'BlockSize', 16)           % parametry. Pokud ne, použije
    assignin('base', 'Thresold', 0.1)           % výchozí hodnoty
end

BlockSize = evalin('base', 'BlockSize');        % Načte hodnoty z workspace
Thresold = evalin('base', 'Thresold');


% Identifikace oblasti s papilárními liniemi
[handles.normim, handles.mask] = ridgesegment(handles.fingerprint, BlockSize, Thresold);
axes(handles.axsFingerprint); %Výběr plochy pro kreslení
imshow(handles.normim);

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles); % Uložení výsledku jako globální proměná

set(handles.panAxsFingerprint,'Title','Otisk s identifikovaným pozadím a popředím');

%set(handles.buttonRidgeOrient,'enable','on')


function btnRidgeOrient_Callback(hObject, eventdata, handles)

handles.t = cputime; 

if evalin('base','exist(''GradientSigma'')') == 0      % Zjišťuje zda jsou změnené
    assignin('base', 'GradientSigma', 1)               % parametry. Pokud ne, použije
    assignin('base', 'BlockSigma', 5)                  % výchozí hodnoty
    assignin('base', 'OrientSmoothSigma',5)
end

GradientSigma = evalin('base', 'GradientSigma');        % Načte hodnoty z workspace
BlockSigma = evalin('base', 'BlockSigma');
OrientSmoothSigma = evalin('base', 'OrientSmoothSigma');

% Odhad orientací papilárních linií
[handles.orientim, handles.reliability] = ridgeorient(handles.normim, GradientSigma, BlockSigma, OrientSmoothSigma);
axes(handles.axsFingerprint);
plotridgeorient(handles.orientim, 20, handles.fingerprint, 2)
set(handles.panAxsFingerprint,'Title','Odhad orientací papilárních linií');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


%set(handles.buttonRidgeFreq,'enable','on')


function btnRidgeFreq_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''Blksze'')') == 0     
    assignin('base', 'Blksze', 32)               
    assignin('base', 'Windsze', 5)                  
    assignin('base', 'MinWaveLength',5)
    assignin('base', 'MaxWaveLength',15)
end

Blksze = evalin('base', 'Blksze');        
Windsze = evalin('base', 'Windsze');
MinWaveLength = evalin('base', 'MinWaveLength');
MaxWaveLength = evalin('base', 'MaxWaveLength');

% Odhad frekvencí papilárních linií
[handles.freq, handles.medfreq] = ridgefreq(handles.normim, handles.mask, handles.orientim, Blksze, Windsze, MinWaveLength, MaxWaveLength);
axes(handles.axsFingerprint);
imshow(handles.freq,3)
set(handles.panAxsFingerprint,'Title','Odhad frekvencí papilárních linií');
freq = (handles.medfreq).*(handles.mask);

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.buttonRidgeFilter,'enable','on')


function btnRidgeFilter_Callback(hObject, eventdata, handles)

handles.t = cputime; 


if evalin('base','exist(''Ky'')') == 0     
    assignin('base', 'Kx', 0.5)               
    assignin('base', 'Ky', 0.5)
    assignin('base', 'ReliableParam', 0.4)
end

Kx = evalin('base', 'Kx');
Ky = evalin('base', 'Ky');
ReliableParam = evalin('base', 'ReliableParam');


handles.newim = ridgefilter(handles.normim, handles.orientim, handles.freq, Kx, Ky);
axes(handles.axsFingerprint);
%imshow(handles.newim,4);
%set(handles.panAxsFingerprint,'Title','Otisk prstu po filtraci za pomoci Gaborových filtrů');

handles.binim = handles.newim > 0;

imshow((handles.binim).*(handles.mask).*((handles.reliability)>ReliableParam), 7)
set(handles.panAxsFingerprint,'Title','Otisk prstu po filtraci za pomoci Gaborových filtrů');
imshow(handles.binim);

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);

%set(handles.btnThining,'enable','on')


function btnStftParam_Callback(hObject, eventdata, handles)

StftParam();


function btnStftRun_Callback(hObject, eventdata, handles)

handles.t = cputime; 


[handles.oimg,handles.fimg,handles.bwimg,handles.eimg,handles.enhimg] =  fft_enhance_cubs(handles.fingerprint);
axes(handles.axsFingerprint);
imshow(handles.enhimg);
set(handles.panAxsFingerprint,'Title','Otisk vylepšený pomocí STFT');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


function btnStftThreshold_Callback(hObject, eventdata, handles)

handles.t = cputime; 


%handles.binim = otsu_thresh(handles.enhimg,2);
%handles.binim=handles.enhimg(:,:,1)>160;
level = graythresh(handles.enhimg);
handles.binim = im2bw(handles.enhimg,level)
axes(handles.axsFingerprint);
imshow(handles.binim, []);
set(handles.panAxsFingerprint,'Title','Otisk po aplikaci Otsuova prahu');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


function btnHistEqualizaction_Callback(hObject, eventdata, handles)

handles.t = cputime; 

    
handles.fingerprint=histeq(handles.fingerprint);
axes(handles.axsFingerprint);
imshow(handles.fingerprint);
set(handles.panAxsFingerprint,'Title','Ekvalizovaný otisk');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


function btnFftApplication_Callback(hObject, eventdata, handles)

handles.t = cputime; 


W = inputdlg('Zadejte faktor FFT (0-1, nejlepší výsledek s 0.45):');
W = str2double(char(W));
handles.fingerfft=fftenhance(handles.fingerprint,W)
imshow(handles.fingerfft);
set(handles.panAxsFingerprint,'Title','Otisk po aplikaci FFT');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);


function pushbutton43_Callback(hObject, eventdata, handles)

handles.t = cputime; 

%handles.binim = adaptive_thres(double(handles.fingerfft),32);
level = graythresh(handles.fingerfft);
handles.binim = im2bw(handles.fingerfft,level)
imshow(handles.binim);
set(handles.panAxsFingerprint,'Title','Otisk po binarizaci');

handles.e = handles.e + cputime-handles.t;

guidata(hObject, handles);
