function varargout = Rev_deid(varargin)
% REV_DEID MATLAB code for Rev_deid.fig
%      REV_DEID, by itself, creates a new REV_DEID or raises the existing
%      singleton*.
%
%      H = REV_DEID returns the handle to a new REV_DEID or the handle to
%      the existing singleton*.
%
%      REV_DEID('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in REV_DEID.M with the given input arguments.
%
%      REV_DEID('Property','Value',...) creates a new REV_DEID or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before Rev_deid_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to Rev_deid_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help Rev_deid

% Last Modified by GUIDE v2.5 28-May-2015 09:42:31

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @Rev_deid_OpeningFcn, ...
                   'gui_OutputFcn',  @Rev_deid_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


% --- Executes just before Rev_deid is made visible.
function Rev_deid_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to Rev_deid (see VARARGIN)

% Choose default command line output for Rev_deid
handles.output = hObject;

global globvar;

addpath Funkce
addpath Promenne
%% load model
load cAAM.mat
%% fitting related parameters
num_of_scales_used = 2;
num_of_iter = [100 100];%[50 50];
%% landmark initializations
load initializations_LFPW
%% get image and positions

[filename,pathname]=uigetfile({'*.jpg;*.tif;*.png;*.pgm;*.bmp;','All Image Files';'*.*','All Files' },'Vyberte obraz');
txt=filename(1:length(filename)-4);
txt=strcat(pathname(1:length(pathname)-9),'Positions\',txt,'.txt');

pathfile=strcat(pathname,filename);
globvar.input=imread(pathfile);


if size(globvar.input, 3) == 3
    globvar.inp = double(rgb2gray(globvar.input));
    globvar.input = rgb2gray(globvar.input);
else
    globvar.inp = double(globvar.input);
end
% globvar.input_orig=globvar.input;

vstup=fopen(txt,'r');
x_o=fscanf(vstup,'%d',1);
y_o=fscanf(vstup,'%d',1);
w_o=fscanf(vstup,'%d',1);
h_o=fscanf(vstup,'%d',1);
point_o=zeros(8,2);
for i=1:8
    point_o(i,:)=fscanf(vstup,'%d',2);
end
fclose(vstup);

%% 
s0 = cAAM.shape{1}.s0;
trans(1,1)=((point_o(8,1)+point_o(1,1))/2);
trans(1,2)=((point_o(8,2)+point_o(1,2))/2);
scl(1)=1;
globvar.current_shape = scl(1)*reshape(s0, cAAM.num_of_points, 2) + repmat(trans(1, :), cAAM.num_of_points, 1);

SZAJ_CS=((globvar.current_shape(49,2)+globvar.current_shape(55,2))/2);

ccc = ((point_o(6,2)+point_o(7,2)) / 2);
ccc2 = ((point_o(4,2)+point_o(5,2)) / 2);

sc1 = ((ccc - trans(1, 2)) / s0(28,2));
sc2 = ((ccc2 - trans(1, 2)) / SZAJ_CS);

scl(1)=sc1+sc2;
globvar.current_shape = scl(1)*reshape(s0, cAAM.num_of_points, 2) + repmat(trans(1, :), cAAM.num_of_points, 1);

% cs_mod = round(globvar.current_shape);
globvar.inp = imresize(globvar.inp, 1/scl(1));
globvar.current_shape = (1/scl(1))*(globvar.current_shape);

%% Fitting an AAM using Fast-SIC algorithm
sc = 2.^(cAAM.scales-1);
for ii = num_of_scales_used:-1:1
    globvar.current_shape = globvar.current_shape /sc(ii);

    % indices for masking pixels out
    globvar.ind_in = cAAM.coord_frame{ii}.ind_in;
    ind_out = cAAM.coord_frame{ii}.ind_out;
    ind_in2 = cAAM.coord_frame{ii}.ind_in2;
    ind_out2 = cAAM.coord_frame{ii}.ind_out2;
    globvar.resolution = cAAM.coord_frame{ii}.resolution;

    globvar.A0 = cAAM.texture{ii}.A0;
    globvar.A = cAAM.texture{ii}.A;
    AA0 = cAAM.texture{ii}.AA0;
    AA = cAAM.texture{ii}.AA;
    
    for i = 1:num_of_iter(ii)

%         figure(1);clf;
%         imshow(imresize(globvar.inp, [size(globvar.inp, 1)/sc(ii) size(globvar.inp, 2)/sc(ii)]), [], 'Border','tight'); hold on;
        trimesh(cAAM.coord_frame{ii}.triangles, globvar.current_shape(:,1),globvar.current_shape(:,2),'Color',(i/num_of_iter(ii)).*[0 1 1],'LineStyle','-');hold off;

        % Warp image
        Iw = warp_image(cAAM.coord_frame{ii}, globvar.current_shape*sc(ii), globvar.inp);
        I = Iw(:); I(ind_out) = [];
        II = Iw(:); II(ind_out2) = [];

        % compute reconstruction Irec
        if (i == 1)
        globvar.c = globvar.A'*(I - globvar.A0) ;
        else
        globvar.c = globvar.c + dc;
        end
        Irec = zeros(globvar.resolution(1), globvar.resolution(2));
        Irec(globvar.ind_in) = globvar.A0 + globvar.A*globvar.c;
%                         figure(2)
%                         imshow(Irec,[], 'Border','tight');
        img_store=Irec;
        % compute gradients of Irec
        [Irecx Irecy] = gradient(Irec);
        Irecx(ind_out2) = 0; Irecy(ind_out2) = 0;
        Irec(ind_out2) = [];
        Irec = Irec(:);

        % compute J from the gradients of Irec
        J = image_jacobian(Irecx, Irecy, cAAM.texture{ii}.dW_dp, cAAM.shape{ii}.n_all);
        J(ind_out2, :) = [];

        % compute Jfsic and Hfsic
        Jfsic = J - AA*(AA'*J);
        Hfsic = Jfsic' * Jfsic;
        inv_Hfsic = inv(Hfsic);

        % update
        dqp = inv_Hfsic * Jfsic'*(II-AA0);
        dc = AA'*(II - Irec - J*dqp);

        % This function updates the shape in an inverse compositional fashion
        globvar.current_shape =  compute_warp_update(globvar.current_shape, dqp, cAAM.shape{ii}, cAAM.coord_frame{ii});
%         figure(3)
%         imshow(globvar.inp, [], 'Border','tight'); hold on; plot(globvar.current_shape(:,1)* sc(ii), globvar.current_shape(:,2)* sc(ii), '.', 'MarkerSize',11); hold off;
    end
    globvar.current_shape(:,1) = globvar.current_shape(:, 1) * sc(ii) ;
    globvar.current_shape(:,2) = globvar.current_shape(:, 2) * sc(ii) ;
end
% imshow(globvar.inp, [], 'Border','tight'); hold on; plot(globvar.current_shape(:,1), globvar.current_shape(:,2), '.', 'MarkerSize',11);hold off;
% figure;
% unwarp(img_store,cAAM.coord_frame{ii}, globvar.current_shape*sc(ii), globvar.inp);

axes(handles.originalax);
globvar.output=globvar.input;
[s,ss]=size(globvar.output);
colormap gray
imagesc(1:s,1:ss,globvar.input);
axis off

axes(handles.deidax);
colormap gray
imagesc(globvar.output);
axis off

globvar.d=globvar.c;

globvar.ii = ii;
globvar.sc = sc;
globvar.cAAMcordframeii = cAAM.coord_frame{ii};

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes Rev_deid wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = Rev_deid_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in deidfunc.
function deidfunc_Callback(hObject, eventdata, handles)
% hObject    handle to deidfunc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
mm=get(handles.metodapopup,'Value');
global globvar;
zadejpanel(handles);
chyba(handles);

if globvar.chyba == 0

switch(mm)
    
    %%HAMMING
    case {2}
        h=hamming(globvar.do);
        h=2000*h;
        globvar.c(globvar.od:((globvar.od+globvar.do)-1))=h;
        
    %%SINUS    
    case {3}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = sin(globvar.c(globvar.od));
        else
            globvar.c(globvar.od:globvar.do) = sin(globvar.c(globvar.od:globvar.do));
        end
    
    %%COSINUS
    case {4}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = cos(globvar.c(globvar.od));
        else
            globvar.c(globvar.od:globvar.do) = cos(globvar.c(globvar.od:globvar.do));
        end
        
    %%TANGENT
    case {5}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = tan(globvar.c(globvar.od));
        else
            globvar.c(globvar.od:globvar.do) = tan(globvar.c(globvar.od:globvar.do));
        end
        
    %%EXPONENTIAL
    case {6}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = exp(globvar.c(globvar.od));
        else
            globvar.c(globvar.od:globvar.do) = exp(globvar.c(globvar.od:globvar.do));
        end
    
    %%ABSOLUTE
    case {7}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = abs(globvar.c(globvar.od));
        else
            globvar.c(globvar.od:globvar.do) = abs(globvar.c(globvar.od:globvar.do));
        end
        
    %%LN
    case {8}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = abs(log(globvar.c(globvar.od)));
        else
            globvar.c(globvar.od:globvar.do) = abs(log(globvar.c(globvar.od:globvar.do)));
        end
        
    %%LOG2
    case {9}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = abs(log2(globvar.c(globvar.od)));
        else
            globvar.c(globvar.od:globvar.do) = abs(log2(globvar.c(globvar.od:globvar.do)));
        end
        
    %%LOG10
    case {10}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = abs(log10(globvar.c(globvar.od)));
        else
            globvar.c(globvar.od:globvar.do) = abs(log10(globvar.c(globvar.od:globvar.do)));
        end
        
    %%SQRT
    case {11}
        if (globvar.od==globvar.do)
            globvar.c(globvar.od) = abs(sqrt(globvar.c(globvar.od)));
        else
            globvar.c(globvar.od:globvar.do) = abs(sqrt(globvar.c(globvar.od:globvar.do)));
        end 
end

aplikuj;
zobrazit(handles);

end


function aplikuj(handles)
global globvar;

Irec = zeros(globvar.resolution(1), globvar.resolution(2));
Irec(globvar.ind_in) = globvar.A0 + globvar.A*globvar.c;
img_store = Irec;

globvar.output = uint8(unwarp(img_store,globvar.cAAMcordframeii, globvar.current_shape*globvar.sc(globvar.ii), globvar.inp));
globvar.c=globvar.d;


function zobrazit(handles)

global globvar;
axes(handles.deidax);
colormap gray
imagesc(globvar.output);
axis off


% --- Executes on button press in deid2.
function deid2_Callback(hObject, eventdata, handles)
% hObject    handle to deid2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global globvar;

zadejpokr(handles);

switch (globvar.pohlavy)
    
    case {1}
        globvar.c([3 6 8 9 10 11 13 14 16 20 22 24 25 26])=0;
        globvar.c([1 2 4 5 7 12 15 17 18])=1000;
        
        switch (globvar.oci)
                        
            case {1}
                globvar.c([15 18 19 21])=0;
                globvar.c([17 23 34])=0;   
                globvar.c([28 59])=0;      

                globvar.c([1 2 4 5 7 12 27 29 30 32 33])=700;
                if globvar.vyraz == 2
                    globvar.c([1 2 3 12 27 21 48]) = 1000;
                elseif globvar.vyraz == 1
                    globvar.c([29 30 32 33])=1000;
                end

            case {2}
                globvar.c([17 23 34])=0;    
                globvar.c([28 59])=0;       
                globvar.c([1 2 4 5 7 12 27 29 30 32 33])=0;

                globvar.c([15 18 19 21 48])=700; 
                if globvar.vyraz == 2
                    globvar.c([21 48]) = 2000;
                elseif globvar.vyraz == 1
                    globvar.c([15 18 19])=2000;
                end

            case {3}
                globvar.c([15 18 19 21])=0; 
                globvar.c([28 59])=0;       
                globvar.c([1 2 4 5 7 12 27 29 30 32 33])=0; 
                
                globvar.c([17 23 34])=2000;   

            case {4}
                globvar.c([17 23 34])=0;    
                globvar.c([15 18 19 21])=0; 
                globvar.c([1 2 4 5 7 12 27 29 30 32 33])=0;   

                globvar.c([28 59])=2000;       
            
            
        end
        
        if globvar.bryle == 1
            i=1;
        elseif globvar.bryle == 2
            globvar.c([41 51 56 74])=1000;
        end
        
        
        case {2}
            
            globvar.c([1 2 3 4 5 7 12 15 17 18 19 21 23 27 28 29 30])=0;
%                     globvar.c([3 6 8 9 10 11 13 14 16 20 22 24 25])=1000;
            switch (globvar.oci)
                case {1}
                    globvar.c([20 26])=0;
                    globvar.c([6 10 14 16 31])=0;
                    globvar.c([22 24])=0;

                    globvar.c([3 8 9 11 13 25 35 39 40 43 46])=700;
                    if globvar.vyraz == 2
                        globvar.c([3 35]) = 2000;
                    elseif globvar.vyraz == 1
                        globvar.c([8 9 25 39 40 43 46])=1200;
                    end

                case {2}
                    globvar.c([6 10 14 16 31])=0;
                    globvar.c([22 24])=0;
                    globvar.c([3 8 9 11 13 25 35 39 40 43 46])=0;
                   
                    globvar.c([20 26])=700;
                    if globvar.vyraz==2
                        globvar.c([20 26]) = 1200;
                    elseif globvar.vyraz ==1
                        globvar.c([26])=2000;
                    end

                case {3}
                    globvar.c([20 26])=0;
                    globvar.c([22 24])=0;
                    globvar.c([3 8 9 11 13 25 35 39 40 43 46])=0;
                    
                    globvar.c([6 10 14 16 31])=700;
                    if globvar.vyraz==2
                        globvar.c([6 10 31]) = 1000;
                    elseif globvar.vyraz ==1
                        globvar.c([16])=2000;
                    end

                case 'u'
                    globvar.c([6 10 14 16 31])=0;
                    globvar.c([20 26])=0;
                    globvar.c([3 8 9 11 13 25 35 39 40 43 46])=0;
                    
                    globvar.c([22 24])=2000;       

            end
        if globvar.bryle == 1
            i=1;
        elseif globvar.bryle == 2
            globvar.c([25 26 35 43 49])=1000;
        end
end
        
aplikuj;
zobrazit(handles);


function zadejpanel(handles)

global globvar;
globvar.od = str2num(get(handles.edOd,'string'));
globvar.do = str2num(get(handles.edDo,'string'));


function zadejpokr(handles)

global globvar;
globvar.pohlavy = get(handles.poppohl,'Value');
globvar.oci = get(handles.ocipoz,'Value');
globvar.vyraz = get(handles.vyrpop,'Value');
globvar.bryle = get(handles.brylean,'Value');


function chyba(handles)

ch=get(handles.metodapopup,'Value');
global globvar

if ch==2
    if ((globvar.od<0) || (globvar.od>200) || (globvar.do<0) || (globvar.do>200))
        set(handles.chyba, 'String','Cisla musi byt mezi 0 a 200!');
        set(handles.chyba, 'Visible', 'ON');
        globvar.chyba = 1;
    else
        set(handles.chyba, 'Visible', 'OFF');
        globvar.chyba = 0;
    end
    
    if ((globvar.od+globvar.do) > 200)
        set(handles.chyba, 'String','Zla pozice');
        set(handles.chyba, 'Visible', 'ON');
        globvar.chyba = 1;
    else
        set(handles.chyba, 'Visible', 'OFF');
        globvar.chyba = 0;
    end
    
else
    if ((globvar.od<0) || (globvar.od>200) || (globvar.do<0) || (globvar.do>200))
        set(handles.chyba, 'String','Cisla musi byt mezi 0 a 200!');
        set(handles.chyba, 'Visible', 'ON');
        globvar.chyba = 1;
    else
        set(handles.chyba, 'Visible', 'OFF');
        globvar.chyba = 0;
    end
end


% --- Executes on selection change in metodapopup.
function metodapopup_Callback(hObject, eventdata, handles)
% hObject    handle to metodapopup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

m2m=get(handles.metodapopup,'Value');
if m2m==2 
    set(handles.do,'String','Delka okna');
    set(handles.edOd,'String','1');
    set(handles.edDo,'String','5');
    
else
    set(handles.do,'String','Pozice DO');
    set(handles.edOd,'String','1');
    set(handles.edDo,'String','10');
end


% --- Executes during object creation, after setting all properties.
function metodapopup_CreateFcn(hObject, eventdata, handles)
% hObject    handle to metodapopup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function edOd_Callback(hObject, eventdata, handles)
% hObject    handle to edOd (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edOd as text
%        str2double(get(hObject,'String')) returns contents of edOd as a double


% --- Executes during object creation, after setting all properties.
function edOd_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edOd (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function edDo_Callback(hObject, eventdata, handles)
% hObject    handle to edDo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edDo as text
%        str2double(get(hObject,'String')) returns contents of edDo as a double


% --- Executes during object creation, after setting all properties.
function edDo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edDo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in poppohl.
function poppohl_Callback(hObject, eventdata, handles)
% hObject    handle to poppohl (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns poppohl contents as cell array
%        contents{get(hObject,'Value')} returns selected item from poppohl


% --- Executes during object creation, after setting all properties.
function poppohl_CreateFcn(hObject, eventdata, handles)
% hObject    handle to poppohl (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in ocipoz.
function ocipoz_Callback(hObject, eventdata, handles)
% hObject    handle to ocipoz (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns ocipoz contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ocipoz


% --- Executes during object creation, after setting all properties.
function ocipoz_CreateFcn(hObject, eventdata, handles)
% hObject    handle to ocipoz (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in vyrpop.
function vyrpop_Callback(hObject, eventdata, handles)
% hObject    handle to vyrpop (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns vyrpop contents as cell array
%        contents{get(hObject,'Value')} returns selected item from vyrpop


% --- Executes during object creation, after setting all properties.
function vyrpop_CreateFcn(hObject, eventdata, handles)
% hObject    handle to vyrpop (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in brylean.
function brylean_Callback(hObject, eventdata, handles)
% hObject    handle to brylean (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns brylean contents as cell array
%        contents{get(hObject,'Value')} returns selected item from brylean


% --- Executes during object creation, after setting all properties.
function brylean_CreateFcn(hObject, eventdata, handles)
% hObject    handle to brylean (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in Novyobr.
function Novyobr_Callback(hObject, eventdata, handles)
% hObject    handle to Novyobr (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global globvar;

addpath Funkce
addpath Promenne
%% load model
load cAAM.mat
%% fitting related parameters
num_of_scales_used = 2;
num_of_iter = [100 100];%[50 50];
%% landmark initializations
load initializations_LFPW
%% get image and positions

[filename,pathname]=uigetfile({'*.jpg;*.tif;*.png;*.pgm;*.bmp;','All Image Files';'*.*','All Files' },'Vyberte obraz');
txt=filename(1:length(filename)-4);
txt=strcat(pathname(1:length(pathname)-9),'Positions\',txt,'.txt');

pathfile=strcat(pathname,filename);
globvar.input=imread(pathfile);


if size(globvar.input, 3) == 3
    globvar.inp = double(rgb2gray(globvar.input));
    globvar.input = rgb2gray(globvar.input);
else
    globvar.inp = double(globvar.input);
end

vstup=fopen(txt,'r');
x_o=fscanf(vstup,'%d',1);
y_o=fscanf(vstup,'%d',1);
w_o=fscanf(vstup,'%d',1);
h_o=fscanf(vstup,'%d',1);
point_o=zeros(8,2);
for i=1:8
    point_o(i,:)=fscanf(vstup,'%d',2);
end
fclose(vstup);

%% 
s0 = cAAM.shape{1}.s0;
trans(1,1)=((point_o(8,1)+point_o(1,1))/2);
trans(1,2)=((point_o(8,2)+point_o(1,2))/2);
scl(1)=1;
globvar.current_shape = scl(1)*reshape(s0, cAAM.num_of_points, 2) + repmat(trans(1, :), cAAM.num_of_points, 1);

SZAJ_CS=((globvar.current_shape(49,2)+globvar.current_shape(55,2))/2);

ccc = ((point_o(6,2)+point_o(7,2)) / 2);
ccc2 = ((point_o(4,2)+point_o(5,2)) / 2);

sc1 = ((ccc - trans(1, 2)) / s0(28,2));
sc2 = ((ccc2 - trans(1, 2)) / SZAJ_CS);

scl(1)=sc1+sc2;
globvar.current_shape = scl(1)*reshape(s0, cAAM.num_of_points, 2) + repmat(trans(1, :), cAAM.num_of_points, 1);

% cs_mod = round(globvar.current_shape);
globvar.inp = imresize(globvar.inp, 1/scl(1));
globvar.current_shape = (1/scl(1))*(globvar.current_shape);

%% Fitting an AAM using Fast-SIC algorithm
sc = 2.^(cAAM.scales-1);
for ii = num_of_scales_used:-1:1
    globvar.current_shape = globvar.current_shape /sc(ii);

    % indices for masking pixels out
    globvar.ind_in = cAAM.coord_frame{ii}.ind_in;
    ind_out = cAAM.coord_frame{ii}.ind_out;
    ind_in2 = cAAM.coord_frame{ii}.ind_in2;
    ind_out2 = cAAM.coord_frame{ii}.ind_out2;
    globvar.resolution = cAAM.coord_frame{ii}.resolution;

    globvar.A0 = cAAM.texture{ii}.A0;
    globvar.A = cAAM.texture{ii}.A;
    AA0 = cAAM.texture{ii}.AA0;
    AA = cAAM.texture{ii}.AA;
    
    for i = 1:num_of_iter(ii)

%         figure(1);clf;
%         imshow(imresize(globvar.inp, [size(globvar.inp, 1)/sc(ii) size(globvar.inp, 2)/sc(ii)]), [], 'Border','tight'); hold on;
        trimesh(cAAM.coord_frame{ii}.triangles, globvar.current_shape(:,1),globvar.current_shape(:,2),'Color',(i/num_of_iter(ii)).*[0 1 1],'LineStyle','-');hold off;

        % Warp image
        Iw = warp_image(cAAM.coord_frame{ii}, globvar.current_shape*sc(ii), globvar.inp);
        I = Iw(:); I(ind_out) = [];
        II = Iw(:); II(ind_out2) = [];

        % compute reconstruction Irec
        if (i == 1)
        globvar.c = globvar.A'*(I - globvar.A0) ;
        else
        globvar.c = globvar.c + dc;
        end
        Irec = zeros(globvar.resolution(1), globvar.resolution(2));
        Irec(globvar.ind_in) = globvar.A0 + globvar.A*globvar.c;
%                         figure(2)
%                         imshow(Irec,[], 'Border','tight');
        img_store=Irec;
        % compute gradients of Irec
        [Irecx Irecy] = gradient(Irec);
        Irecx(ind_out2) = 0; Irecy(ind_out2) = 0;
        Irec(ind_out2) = [];
        Irec = Irec(:);

        % compute J from the gradients of Irec
        J = image_jacobian(Irecx, Irecy, cAAM.texture{ii}.dW_dp, cAAM.shape{ii}.n_all);
        J(ind_out2, :) = [];

        % compute Jfsic and Hfsic
        Jfsic = J - AA*(AA'*J);
        Hfsic = Jfsic' * Jfsic;
        inv_Hfsic = inv(Hfsic);

        % update
        dqp = inv_Hfsic * Jfsic'*(II-AA0);
        dc = AA'*(II - Irec - J*dqp);

        % This function updates the shape in an inverse compositional fashion
        globvar.current_shape =  compute_warp_update(globvar.current_shape, dqp, cAAM.shape{ii}, cAAM.coord_frame{ii});
%         figure(3)
%         imshow(globvar.inp, [], 'Border','tight'); hold on; plot(globvar.current_shape(:,1)* sc(ii), globvar.current_shape(:,2)* sc(ii), '.', 'MarkerSize',11); hold off;
    end
    globvar.current_shape(:,1) = globvar.current_shape(:, 1) * sc(ii) ;
    globvar.current_shape(:,2) = globvar.current_shape(:, 2) * sc(ii) ;
end
% imshow(globvar.inp, [], 'Border','tight'); hold on; plot(globvar.current_shape(:,1), globvar.current_shape(:,2), '.', 'MarkerSize',11);hold off;
% figure;
% unwarp(img_store,cAAM.coord_frame{ii}, globvar.current_shape*sc(ii), globvar.inp);

axes(handles.originalax);
globvar.output=globvar.input;
[s,ss]=size(globvar.output);
colormap gray
imagesc(1:s,1:ss,globvar.input);
axis off

axes(handles.deidax);
colormap gray
imagesc(globvar.output);
axis off

globvar.d=globvar.c;

globvar.ii = ii;
globvar.sc = sc;
globvar.cAAMcordframeii = cAAM.coord_frame{ii};
