function varargout = deidface(varargin)
% DEIDFACE MATLAB code for deidface.fig
%      DEIDFACE, by itself, creates a new DEIDFACE or raises the existing
%      singleton*.
%
%      H = DEIDFACE returns the handle to a new DEIDFACE or the handle to
%      the existing singleton*.
%
%      DEIDFACE('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in DEIDFACE.M with the given input arguments.
%
%      DEIDFACE('Property','Value',...) creates a new DEIDFACE or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before deidface_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to deidface_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 deidface

% Last Modified by GUIDE v2.5 27-May-2015 11:51:16

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @deidface_OpeningFcn, ...
                   'gui_OutputFcn',  @deidface_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 deidface is made visible.
function deidface_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 deidface (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

global promglob;

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

vstup=fopen(txt,'r');
promglob.x=fscanf(vstup,'%d',1);
promglob.y=fscanf(vstup,'%d',1);
promglob.w=fscanf(vstup,'%d',1);
promglob.h=fscanf(vstup,'%d',1);
promglob.point=zeros(8,2);
for i=1:8
    promglob.point(i,:)=fscanf(vstup,'%d',2);
end
fclose(vstup);

promglob.pathfile=strcat(promglob.pathname,promglob.filename);
promglob.input=imread(promglob.pathfile);
%set (axes, 'Visible', 'off');

if size(promglob.input, 3) == 3
    promglob.input = rgb2gray(promglob.input);
end

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

axes(handles.deidax);
colormap gray
imagesc(promglob.output);
axis off
% UIWAIT makes deidface wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = deidface_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;

function mezichyba (handles)
mm=get(handles.metodapopup,'Value');
global promglob
if ((mm==2) || (mm==4) || (mm==5) || (mm==9) || (mm==10) || (mm==11) || (mm==12) || (mm==13) || (mm==16))
    if ((mm==2) || (mm==9) || (mm==10) || (mm==11) || (mm==12) || (mm==13))
        pr = str2num(get(handles.zadejcislo, 'String'));
        if ((pr<0) || (pr>255))
            set(handles.chybatext, 'String','Cislo musi byt mezi 0 a 255!');
            set(handles.chybatext, 'Visible', 'ON');
            promglob.chyba = 1;
        else
            promglob.chyba = 0;
            set(handles.chybatext, 'Visible', 'OFF');
        end
    elseif ((mm==4) || (mm==5))
        pr = str2num(get(handles.zadejcislo, 'String'));
        if ((pr<1) || (pr>64))
            set(handles.chybatext, 'String','Cislo musi byt mezi 1 a 64!');
            set(handles.chybatext, 'Visible', 'ON');
            promglob.chyba = 1;
        else
            promglob.chyba = 0;
            set(handles.chybatext, 'Visible', 'OFF');
        end
    elseif mm==16
        pr = str2num(get(handles.zadejcislo, 'String'));
        if ((pr<2) || (pr>promglob.kspo))
            ksamestr=strcat('Vyberte cislo mezi 2 a   ',num2str(promglob.kspo));
            set(handles.chybatext, 'String',ksamestr);
            set(handles.chybatext, 'Visible', 'ON');
            promglob.chyba = 1;
        else
            promglob.chyba = 0;
            set(handles.chybatext, 'Visible', 'OFF');
        end
    end
end

function zadejcislo_Callback(hObject, eventdata, handles)
% hObject    handle to zadejcislo (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 zadejcislo as text
%        str2double(get(hObject,'String')) returns contents of zadejcislo as a double


% --- Executes during object creation, after setting all properties.
function zadejcislo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to zadejcislo (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 button press in deidpush2.
function deidpush2_Callback(hObject, eventdata, handles)
% hObject    handle to deidpush2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global promglob
mezichyba(handles);
if promglob.chyba ~= 1
   deidpush_Callback(hObject, eventdata, handles);
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)
global promglob
m2m=get(handles.metodapopup,'Value');
if ((m2m==2) || (m2m==4) || (m2m==5) || (m2m==9) || (m2m==10) || (m2m==11) || (m2m==12) || (m2m==13) || (m2m==16))
    set(handles.cislopanel, 'Visible', 'ON');
    set(handles.deidpush, 'Visible', 'OFF');
    set(handles.chybatext, 'Visible', 'OFF');
    if ((m2m==2) || (m2m==10) || (m2m==11) || (m2m==12) || (m2m==13))
        set(handles.zadejcislo,'String','0');
        set(handles.zadejtext, 'String', 'Zadejte cislo mezi 0 a 255');
    elseif m2m==9
        set(handles.zadejcislo,'String','128');
        set(handles.zadejtext, 'String', 'Zadejte cislo mezi 0 a 255');
    elseif ((m2m==4) || (m2m==5))
        set(handles.zadejcislo,'String','1');
        set(handles.zadejtext, 'String', 'Zadejte cislo mezi 1 a 64');
    elseif m2m==16
        set(handles.zadejcislo,'String','2');
        ksamestr=strcat('Vyberte cislo mezi 2 a   ',num2str(promglob.kspo));
        set(handles.zadejtext, 'String', ksamestr);
    end
else
    set(handles.cislopanel, 'Visible', 'OFF');
    set(handles.deidpush, 'Visible', 'ON');
end


function zadejpanel(handles)
global promglob;
m2m=get(handles.metodapopup,'Value');
if ((m2m==2) || (m2m==4) || (m2m==5) || (m2m==9) || (m2m==10) || (m2m==11) || (m2m==12) || (m2m==13) || (m2m==16))
    if ((m2m==2) || (m2m==10) || (m2m==11) || (m2m==12) || (m2m==13))
        promglob.numb = str2num(get(handles.zadejcislo,'string'));
        promglob.defaultanswer = 0;
    elseif ((m2m==4) || (m2m==5) || (m2m==9) || (m2m==16))
        promglob.numb = str2num(get(handles.zadejcislo,'string'));
    end
end
% Hints: contents = cellstr(get(hObject,'String')) returns metodapopup contents as cell array
%        contents{get(hObject,'Value')} returns selected item from metodapopup


% --- 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


% --- Executes on button press in deidpush.
function deidpush_Callback(hObject, eventdata, handles)
% hObject    handle to deidpush (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 promglob;
if ((mm==2) || (mm==4) || (mm==5) || (mm==9) || (mm==10) || (mm==11) || (mm==12) || (mm==13) || (mm==16))
    zadejpanel(handles);
end

switch (mm)
        
    %%Zatemneni
    case {2}

        if promglob.numb>0 
            promglob.output(promglob.y:promglob.y+promglob.h,promglob.x:promglob.x+promglob.w)=promglob.numb;
        else
            promglob.output(promglob.y:promglob.y+promglob.h,promglob.x:promglob.x+promglob.w)=promglob.defaultanswer;
        end
        
    %%Prumerovani
    case {3}

        b=str2num(promglob.filename(1:length(promglob.filename)-4));
        randface=randi(20,1,1);

        while (randface == b)
            randface=randi(20,1,1);
        end

        avejpg=strcat(promglob.pathname,num2str(randface),'.jpg');
        avetxt=strcat(promglob.pathname(1:length(promglob.pathname)-9),'Positions\',num2str(randface),'.txt');

        if exist(avejpg, 'file')
            pr = imread(avejpg);
            pr = uint64(pr);
            promglob.output = uint64(promglob.output);

            vstup=fopen(avetxt,'r');
            xx=fscanf(vstup,'%d',1);
            yy=fscanf(vstup,'%d',1);
            ww=fscanf(vstup,'%d',1);
            hh=fscanf(vstup,'%d',1);
            fclose(vstup);
        else
            fprintf('Soubor %s neexistuje.\n', avejpg);
        end
        

        for i=promglob.y:promglob.y+promglob.h
            o=round((i*(hh+yy))/(promglob.h+promglob.y));
            for j=promglob.x:promglob.x+promglob.w
                s=round((j*(ww+xx))/(promglob.w+promglob.x));

                promglob.output(i,j)=(promglob.output(i,j)+pr(o,s))/2;

            end
        end
        promglob.output=uint8(promglob.output);

    %%Pixelace
    case {4}

        p=promglob.numb;

        if p==0
            disp('Cislo musi byt vetsi nez 0');
        end

        for i=promglob.y:p:promglob.y+promglob.h
            for j=promglob.x:p:promglob.x+promglob.w
                promglob.output(i:(i+p-1),j:(j+p-1))=ones(p).*mean(mean(promglob.output(i:(i+p-1),j:(j+p-1))));
            end
        end

    %%Rozmazani
    case {5}

        b=promglob.numb;
        if b==0
            disp('Cislo musi byt vetsi nez 0');
            %continue;
        end

        out2=promglob.output;
        u=fspecial('gaussian', size(promglob.input), b);
        promglob.output=imfilter(promglob.output, u);

        out2(promglob.y:promglob.y+promglob.h,promglob.x:promglob.x+promglob.w)=promglob.output(promglob.y:promglob.y+promglob.h,promglob.x:promglob.x+promglob.w);
        promglob.output=out2;

    %%Negative
    case {6}

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                promglob.output(i,j)=255-promglob.output(i,j);
            end
        end

    %%Ordinal
    case {7}

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                if promglob.output(i,j)<=51
                    promglob.output(i,j)=20;
                elseif (51<promglob.output(i,j)) && (promglob.output(i,j)<=102)
                    promglob.output(i,j)=80;
                elseif (102<promglob.output(i,j)) && (promglob.output(i,j)<=153)
                    promglob.output(i,j)=130;
                elseif (153<promglob.output(i,j)) && (promglob.output(i,j)<=204)
                    promglob.output(i,j)=180;
                elseif (204<promglob.output(i,j)) && (promglob.output(i,j)<=255)
                    promglob.output(i,j)=220;
                end
            end
        end

    %%Random_Noise
    case {8}

        [m,n]=size(promglob.output);
        R=round(rand(m,n));

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                if R(i,j)==1
                    promglob.output(i,j)=randi(255,1,1);
                end
            end
        end

    %%Treshold
    case {9}

        t=promglob.numb;

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                if promglob.output(i,j)<=t
                    promglob.output(i,j)=0;
                elseif promglob.output(i,j)>t
                    promglob.output(i,j)=255;
                end
            end
        end

    %%Bar_mask
    case{10}

        if (promglob.numb>0)
            promglob.output(promglob.point(6,2)-20:promglob.point(7,2)+20,promglob.point(6,1)-25:promglob.point(7,1)+25)=promglob.numb;
        else
            promglob.output(promglob.point(6,2)-20:promglob.point(7,2)+20,promglob.point(6,1)-25:promglob.point(7,1)+25)=promglob.defaultanswer;
        end

    %%T_mask
    case {11}

        if (promglob.numb>0)
            promglob.output(promglob.point(6,2)-20:promglob.point(7,2)+20,promglob.point(6,1)-25:promglob.point(7,1)+25)=promglob.numb;
            promglob.output(promglob.point(6,2)-12:promglob.point(1,2)+35,promglob.point(1,1)-30:promglob.point(1,1)+30)=promglob.numb;
        else
            promglob.output(promglob.point(6,2)-20:promglob.point(7,2)+20,promglob.point(6,1)-25:promglob.point(7,1)+25)=promglob.defaultanswer;
            promglob.output(promglob.point(6,2)-12:promglob.point(1,2)+35,promglob.point(1,1)-30:promglob.point(1,1)+30)=promglob.defaultanswer;
        end

    %%Mouth_only
    case {12}

        if (promglob.numb>0)
            promglob.output(promglob.y:promglob.point(1,2)+30,promglob.x:promglob.x+promglob.w)=promglob.numb;
        else
            promglob.output(promglob.y:promglob.point(1,2)+30,promglob.x:promglob.x+promglob.w)=promglob.defaultanswer;
        end

    %%Mouth_only_bw
    case {13}

        t=128;

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                if promglob.output(i,j)<=t
                    promglob.output(i,j)=0;
                elseif promglob.output(i,j)>t
                    promglob.output(i,j)=255;
                end
            end
        end

        if (promglob.numb>0)
            promglob.output(promglob.y:promglob.point(1,2)+30,promglob.x:promglob.x+promglob.w)=promglob.numb;
        else
            promglob.output(promglob.y:promglob.point(1,2)+30,promglob.x:promglob.x+promglob.w)=promglob.defaultanswer;
        end

    %%Negative_bw
    case {14}

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                promglob.output(i,j)=255-promglob.output(i,j);
                if promglob.output(i,j)<128
                    promglob.output(i,j)=0;
                else
                    promglob.output(i,j)=255;
                end
            end
        end

    %%Random_Noise_bw
    case {15}

        [m,n]=size(promglob.output);
        R=round(rand(m,n));

        for i=promglob.y:promglob.y+promglob.h
            for j=promglob.x:promglob.x+promglob.w
                if R(i,j)==1
                    promglob.output(i,j)=255 - 255*round(rand(1));
                end
            end
        end

    %%k-Same
    case{16}
        
        k=promglob.numb; 

        out = uint64(promglob.output);

        os=zeros(promglob.kspo,1);    
        first=str2num(promglob.filename(1:length(promglob.filename)-4));

        for f=1:promglob.kspo         

            if ((first==1)&&(k==1))
                continue;
            end

            kface=strcat(promglob.pathname,num2str(f),'.jpg');

            if exist(kface, 'file')
                kk = imread(kface);
                kk = uint64(kk);

                txt2=strcat(promglob.pathname(1:length(promglob.pathname)-9),'Positions\',num2str(f),'.txt');
                vstup=fopen(txt2,'r');
                xx=fscanf(vstup,'%d',1);
                yy=fscanf(vstup,'%d',1);
                ww=fscanf(vstup,'%d',1);
                hh=fscanf(vstup,'%d',1);
            end
            fclose(vstup);

            for i=promglob.y:promglob.y+promglob.h
                o=round((i*(hh+yy))/(promglob.h+promglob.y));
                for j=promglob.x:promglob.x+promglob.w
                    s=round((j*(ww+xx))/(promglob.w+promglob.x));

                    if kk(o,s)>out(i,j)
                        os(f,1) = os(f,1) + (kk(o,s)-out(i,j))^2;
                    elseif kk(o,s)<out(i,j)
                        os(f,1) = os(f,1) + (out(i,j)-kk(o,s))^2;
                    elseif kk(o,s)==out(i,j)
                        os(f,1) = os(f,1);
                    end
                end
            end
        end

        os=sqrt(os);    
        oss=sort(os);  
        r=0;
        a=1; k=k+1;

        for f=1:k

            for p=1:promglob.kspo            
                if ((oss(f,1)==0) && (os(p,1)==0))      
                    break;                                 
                end
                if oss(f,1)==os(p,1)        
                    pp = strcat(promglob.pathname,num2str(p),'.jpg');
                    txt2=strcat(promglob.pathname(1:length(promglob.pathname)-9),'Positions\',num2str(p),'.txt');
                    r=p;
                    break;
                end
            end

            if r==0 
                continue;
            end

            if exist(pp, 'file')    
                for pic=a:k+1
                    a=a+1;
                    eval(['picture' num2str(pic) '=imread(pp);']);
                    eval(['picture' num2str(pic) '=uint64(picture' num2str(pic) ');']);
                    ksameloc=strcat(promglob.pathname(1:length(promglob.pathname)-9),'KSAME\');
                    copyfile(txt2,ksameloc);
                    txta=strcat(ksameloc,num2str(p),'.txt');
                    txtb=strcat(ksameloc,num2str(pic+1000),'.txt');
                    movefile(txta,txtb);
                    break;
                end
            end
        end
        k=k-1;


        for u=1:k
            txtf=strcat(ksameloc,num2str(u+1000),'.txt');
            vstup=fopen(txtf,'r');
            xx=fscanf(vstup,'%d',1);
            yy=fscanf(vstup,'%d',1);
            ww=fscanf(vstup,'%d',1);
            hh=fscanf(vstup,'%d',1);
            fclose(vstup);
            for i=promglob.y:promglob.y+promglob.h
                o=round((i*(hh+yy))/(promglob.h+promglob.y));
                for j=promglob.x:promglob.x+promglob.w
                    s=round((j*(ww+xx))/(promglob.w+promglob.x));

                    eval(['out(i,j)=(out(i,j)+picture' num2str(u) '(o,s));']);
                end
            end
        end
        out=out./k;
        delpath=strcat(ksameloc,'*.txt');
        delete(delpath);
        promglob.output=uint8(out);
end
zobrazit(handles);
promglob.save=promglob.output;
promglob.output=promglob.input;

function zobrazit(handles)

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

% --- 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 promglob

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

vstup=fopen(txt,'r');
promglob.x=fscanf(vstup,'%d',1);
promglob.y=fscanf(vstup,'%d',1);
promglob.w=fscanf(vstup,'%d',1);
promglob.h=fscanf(vstup,'%d',1);
promglob.point=zeros(8,2);
for i=1:8
    promglob.point(i,:)=fscanf(vstup,'%d',2);
end

fclose(vstup);

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

set (axes, 'Visible', 'off');

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

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

% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global promglob;
prompt = {'Nazev'};
dlg_title = 'Zadejte nazev obrazu';
num_lines = 1;
def = {'nazev'};
answer = inputdlg(prompt,dlg_title,num_lines,def);

nazev = strcat(answer{1},'.jpg');
imwrite(uint8(promglob.save),nazev);
