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

% Last Modified by GUIDE v2.5 30-Jan-2015 15:19:26

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

stdN=256;
% read in some picture data
spiral = imread('spiral2.jpeg');
cirklar = imread('cirklar1.jpeg');
handles.kors1 = stripes(stdN);
handles.kors2 = twostripes(stdN);
handles.pkors = crosses( stdN );
handles.linjer = lines( stdN );
handles.prickar = dots( stdN );
handles.prick = spot( stdN );
handles.n_tops = 1;
colormap hot;
cmap = colormap;
%cmap = flipud(cmap);
handles.setmap=cmap;

% convert jpeg files to grayscale images
handles.spiral = rgbtogray(spiral);
handles.cirklar = rgbtogray(cirklar);

% configure the axes
axes(handles.axesRight)
axis off

axes(handles.axesCenter)
axis off

axes(handles.axesLeft);
axis off

imagesc(handles.linjer)
axis off
colormap(handles.setmap)

% defaults
handles.transformExists=0;
handles.current_org=handles.linjer;
handles.filter=1;

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

% Update handles structure
guidata(hObject, handles);

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


% --- Outputs from this function are returned to the command line.
function varargout = Fourier2D_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 selection change in lstCenter.
function lstCenter_Callback(hObject, eventdata, handles)
% hObject    handle to lstCenter (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 lstCenter contents as cell array
%        contents{get(hObject,'Value')} returns selected item from lstCenter

% read in correct filter type
handles.filter = get(hObject,'Value');

if (handles.transformExists)
    % apply specified filter
    handles.current_filtered=applyfilter( handles.current_inv , handles.R , handles.filter );
    % plot
    handles.current_toplot = removetops( handles.current_filtered, handles.n_tops );
    axes(handles.axesCenter);
    imagesc((abs(handles.current_toplot)))
    colormap(handles.setmap)
    axis off
end

% Update handles structure
guidata(hObject, handles);

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

% Hint: listbox 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 btnInverstransform.
function btnInverstransform_Callback(hObject, eventdata, handles)
% hObject    handle to btnInverstransform (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if (handles.transformExists)
    current_iinv = ifft2(handles.current_filtered);

    axes(handles.axesRight);
    imagesc(abs(current_iinv))
    colormap(handles.setmap)
    axis off
    colorbar('NorthOutside')
end
% Update handles structure
guidata(hObject, handles);

% --- Executes on selection change in lstboxLeft.
function lstboxLeft_Callback(hObject, eventdata, handles)
% hObject    handle to lstboxLeft (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 lstboxLeft contents as cell array
%        contents{get(hObject,'Value')} returns selected item from lstboxLeft
val = get(hObject,'Value');
str = get(hObject,'String');

% select focus to leftmost axes
axes(handles.axesLeft);

% choose what image that should be plotted
switch str{val}
    case 'Spiral' 
        handles.current_org=handles.spiral;
    case 'Cirklar'
       handles.current_org=handles.cirklar;       
    case 'Två linjer'
       handles.current_org=handles.kors1;
    case 'Två korsande linjer'
        handles.current_org=handles.kors2;
    case 'Periodiska kors'
        handles.current_org=handles.pkors;
    case 'Ränder'
        handles.current_org=handles.linjer;
    case 'Prickar'
        handles.current_org=handles.prickar;
    case 'Prick'
        handles.current_org=handles.prick;
end
% plot chosen image and turn off axis
imagesc(handles.current_org)
axis off

% Update handles structure
guidata(hObject, handles);


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

% Hint: listbox 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 btnTransform.
function btnTransform_Callback(hObject, eventdata, handles)
% hObject    handle to btnTransform (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Fourier transform current original
inv=fft2(handles.current_org);
% make the logarithmic result the current inverse
handles.current_inv=fftshift(inv);
% tell program transform exists
handles.transformExists=1;
% apply specified filter
handles.current_filtered=applyfilter( handles.current_inv , handles.R , handles.filter );
% remove outliers
handles.current_toplot = removetops( handles.current_filtered, handles.n_tops );
% chose axes, plot and update the handles
axes(handles.axesCenter);
imagesc((abs(handles.current_toplot)))
colormap(handles.setmap)
axis off

% Update handles structure
guidata(hObject, handles);

% --- Standard transform to grayscale
function out = rgbtogray( in )
% RGB to Grayscale conversion using CCIR 601: 
% Y' = 0.299 R' + 0.587 G' + 0.114 B'
out = in(:,:,1)*0.299 + in(:,:,2)*0.587 + in(:,:,3)*0.114; 

function out = applyfilter( in , R, mode )
% applies a hole filter either blocking (mode=2) or letting
% through (mode=3) low frequency signals. Doing nothing is mode=1.
% R sets the the strength of the filter.

if (mode==1) 
   out = in;
   return
end

% check dims and span empty matrix
rows=length(in(:,1));
cols=length(in(1,:));
out = zeros(rows,cols);
middle = [rows/2 cols/2];
halfw=rows/40;
% determine the Rsq by a specific formular letting Rsq vary from 0.5 to 0.1,
% assuming that 0 < R < 1
Rsq = (rows/4*exp(-1.6094*R))^2;
halfw = sqrt(Rsq)/4;
% apply filter
if (mode==2)
    for i = 1:rows
        for j = 1:cols
            if (((i-middle(1))^2+(j-middle(2))^2) < Rsq) 
                out(i,j)=1;
            else
                out(i,j)=in(i,j);
            end
        end
    end
elseif(mode==3)
    for i = 1:rows
        for j = 1:cols
            if (((i-middle(1))^2+(j-middle(2))^2) > Rsq) 
                out(i,j)=1;
            else
                out(i,j)=in(i,j);
            end
        end
    end
elseif(mode==4)
    for i = 1:rows
        for j = 1:cols
            if ((j > i-halfw) && (j < i+halfw))
                out(i,j) = in(i,j);
            else
                out(i,j)=1;
            end
        end
    end
end


% --- Executes on slider movement.
function sliderCenter_Callback(hObject, eventdata, handles)
% hObject    handle to sliderCenter (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

% read in new value
handles.R=get(hObject,'Value');

if (handles.transformExists)
    % apply new filter
    handles.current_filtered=applyfilter( handles.current_inv , handles.R , handles.filter );
    % plot
    axes(handles.axesCenter);
    handles.current_toplot = removetops( handles.current_filtered, handles.n_tops );
    imagesc((abs(handles.current_toplot)))
    axis off
end
% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

handles.R = get(hObject,'Value');

% Update handles structure
guidata(hObject, handles);

function out = stripes( N )
out = zeros(N,N);

first = round(N*3/8);
secnd = round(N*5/8);
width = round(N/20);

for i = (first-width):(first+width)
    out(:,i) = 1;
end
for i = (secnd-width):(secnd+width)
    out(:,i) = 1;
end

function out = twostripes( N )
out = zeros(N,N);

first = round(N*3/8);
secnd = round(N*5/8);
width = round(N/20);

for i = (first-width):(first+width)
    out(:,i) = 1;
    out(i,:) = 1;
end
for i = (secnd-width):(secnd+width)
    out(:,i) = 1;
    out(i,:) = 1;
end

function out = crosses( N )
out = zeros(N,N);

for i = 10:10:N
    out(:,i) = 1;
end
for j = 10:10:N
    out(j,:) = 1;
end


function out = lines( N )
out = zeros(N,N);

for i = 10:10:N
    out(:,i) = 1;
end

function out = dots( N )
out = zeros(N,N);

for i = 10:10:N
    for j = 10:10:N
        out(i,j) = 1;
    end
end

function out = spot ( N )
out = zeros(N,N);
    
for i = 1:N
    for j = 1:N
        if ((i-N/2)^2+(j-N/2)^2 < (N/20)^2) 
            out(i,j)=1;
        end
    end
end

function out = removetops( inA , n_tops )
% for n_tops times, delete the maximum value of the matrix
for i = 1:n_tops
    [colmax,imax] = max(inA);
    [rowmax,jmax]=max(colmax);
    inA(imax(jmax),jmax)=0;
end
out = inA;
