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

% Last Modified by GUIDE v2.5 14-Oct-2003 13:21:51

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @filtuit_OpeningFcn, ...
                   'gui_OutputFcn',  @filtuit_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin & isstr(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 filtuit is made visible.
function filtuit_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 filtuit (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

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


% --- Outputs from this function are returned to the command line.
function varargout = filtuit_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 during object creation, after setting all properties.
function filenameEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filenameEdit (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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


% --- Executes on button press in loadfileButton.
function loadfileButton_Callback(hObject, eventdata, handles)
% hObject    handle to loadfileButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
filename = deblank(get(handles.filenameEdit,'String'));
image = imread(filename);
image = image(:,:,1);

%crop?
axes(handles.imageAxes);
imshow(image);

handles.rawImg = image;
guidata(hObject, handles);
lowpassLevelMenu_Callback(hObject, eventdata, handles);




% --- Executes during object creation, after setting all properties.
function lowpassLevelMenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to lowpassLevelMenu (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

% Hints: contents = get(hObject,'String') returns lowpassLevelMenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from lowpassLevelMenu
    %If the edit field contains text, then parse it as a filter
ndx = get(handles.lowpassLevelMenu,'Value');
string_list = get(handles.lowpassLevelMenu,'String');
level = eval(string_list{ndx});
gSepFilter =[.05,.25,.4,.25,.05];
lpImg = handles.rawImg;
for(iLev = 1:level-1)
    lpImg = conv2(gSepFilter, gSepFilter', lpImg, 'valid');
    lpImg = imresize(lpImg, .5, 'bilinear');
end

axes(handles.lowpassAxes);
imshow(lpImg, [0,255]);

handles.lpImg = lpImg;
guidata(hObject, handles);
filterApplyButton_Callback(hObject, eventdata, handles);


% --- Executes during object creation, after setting all properties.
function edit3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit3 (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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


% --- Executes during object creation, after setting all properties.
function popupmenu2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu2 (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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


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

%Retrive any text in manual entry filter edit field.
manualFilter = deblank(get(handles.filterEdit,'String'));

if(strcmpi(manualFilter,''))
    %If the edit field contains text, then parse it as a filter
    ndx = get(handles.filterMenu,'Value');
    string_list = get(handles.filterMenu,'String');
    filter = eval(string_list{ndx});
else
    %Otherwise use current filter in the popup menu
    filter = eval(manualFilter);
end

axes(handles.filterAxes);
imshow(filter,[-12,12]);

size(handles.lpImg)
size(filter)
filtImg = conv2(handles.lpImg, filter, 'valid');

axes(handles.filteredImgAxes)
set(handles.filterMin,'String',num2str(min(min(filtImg))));
set(handles.filterMax,'String',num2str(max(max(filtImg))));

range = getAutoRange(filtImg, deblank(get(handles.filterRange,'String')));
set(handles.filterBlack, 'String', num2str(range(1)));
set(handles.filterWhite, 'String', num2str(range(2)));
imshow(filtImg, range);

handles.filtImg = filtImg;
guidata(hObject, handles);
rectifyMenu_Callback(hObject, eventdata, handles);


% --- Executes during object creation, after setting all properties.
function rectifyMenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to rectifyMenu (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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

ndx = get(handles.rectifyMenu,'Value');
string_list = get(handles.rectifyMenu,'String');
rect = string_list{ndx};

if(strcmpi(rect,'FullWave'))
    numRect = 1;
    rectImg{1} = abs(handles.filtImg);
elseif(strcmpi(rect,'Squared'))
    numRect = 1;
    rectImg{1} = (handles.filtImg.^2);
    rectImg{1} = (rectImg{1}./(max(max(rectImg{1})))) * 255;
elseif(strcmpi(rect,'HalfWave'))
    numRect = 2;
    rectImg{1} = abs(handles.filtImg) .* (handles.filtImg>0);
    rectImg{2} = abs(handles.filtImg) .* (handles.filtImg<0);
else
    numRect = 1;
    rectImg{1} = handles.filtImg
end

if(numRect==1)
    set(handles.rectifyMin,'String',num2str(min(min(rectImg{1}))));
    set(handles.rectifyMax,'String',num2str(max(max(rectImg{1}))));
else
    set(handles.rectifyMin,'String',num2str(min(min(min(rectImg{1},rectImg{2})))));
    set(handles.rectifyMax,'String',num2str(max(max(max(rectImg{1},rectImg{2})))));   
end

axes(handles.rectify1Axes);
range = getAutoRange(rectImg{1}, deblank(get(handles.rectifyRange,'String')));
set(handles.rectBlack, 'String', num2str(range(1)));
set(handles.rectWhite, 'String', num2str(range(2)));
imshow(rectImg{1}, range);

axes(handles.rectify2Axes);
if(numRect==2)
    range = getAutoRange(rectImg{1}, deblank(get(handles.rectifyRange,'String')));
    imshow(rectImg{2}, range); 
else
    imshow([1]);
end

handles.numRect = numRect;
handles.rectImg = rectImg;
guidata(hObject, handles);
nonlinMenu_Callback(hObject, eventdata, handles);


% --- Executes during object creation, after setting all properties.
function filterEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filterEdit (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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


% --- Executes during object creation, after setting all properties.
function filterMenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filterMenu (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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


% --- Executes during object creation, after setting all properties.
function nonlinMenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to nonlinMenu (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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

ndx = get(handles.nonlinMenu,'Value');
string_list = get(handles.nonlinMenu,'String');
nonlin = string_list{ndx};

handles.numRect

if(strcmpi(nonlin,'SpatialPooling'))
    for(i = 1:handles.numRect)
        img = handles.rectImg{i};
        gSepFilter = [.05,.25,.4,.25,.05];
        nonlinImg{i} = conv2(gSepFilter, gSepFilter', img, 'valid');
    end
elseif(strcmpi(nonlin,'StrongestNeighbor'))
    for(i = 1:handles.numRect)
       cleanimg = handles.rectImg{i};
       img = handles.rectImg{i};
       for(x=-1:1)
           for(y=-1:1)
               img =max(img,shift(cleanimg,[x,y]));
           end
       end
       nonlinImg{i} = img;
    end
else
    nonlinImg = handles.rectImg;    
end

axes(handles.nonlin1Axes);
range = getAutoRange(handles.rectImg{1}, deblank(get(handles.rectifyRange,'String')));
imshow(nonlinImg{1},range);
axes(handles.nonlin2Axes);
if(handles.numRect==2)
    imshow(nonlinImg{2},range);   
else
    imshow([1]);
end

handles.nonlinImg = nonlinImg;
guidata(hObject, handles);
histTargetMenu_Callback(hObject, eventdata, handles);



%-----------------------------------------------------------------------
% -- Non-GUIDE function to set the scale on the current set of axes.
function axesHistScale(handles)
%The function should only be called when the active axes is a histogram.
axesscale = get(handles.axesScale,'String');
if(~isempty(axesscale))
    axis(eval(axesscale));
end
%-----------------------------------------------------------------------


% --- Executes during object creation, after setting all properties.
function axesScale_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axesScale (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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

% --- Executes during object creation, after setting all properties.
function histRange_CreateFcn(hObject, eventdata, handles)
% hObject    handle to histRange (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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


% --- Executes during object creation, after setting all properties.
function filterRange_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filterRange (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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

% --- Executes during object creation, after setting all properties.
function rectifyRange_CreateFcn(hObject, eventdata, handles)
% hObject    handle to rectifyRange (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



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

% --- Executes during object creation, after setting all properties.
function histTargetMenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to histTargetMenu (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
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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

%which image histogram
ndx = get(handles.histTargetMenu,'Value');
string_list = get(handles.histTargetMenu,'String');
imgTarget = string_list{ndx};

if(strcmpi(imgTarget, 'Raw Image'))
    img = handles.rawImg;
elseif(strcmpi(imgTarget, 'Low Pass Image'))
    img = handles.lpImg;
elseif(strcmpi(imgTarget, 'Filtered Image'))
    img = handles.filtImg;
elseif(strcmpi(imgTarget, 'Rectified Image Chan 1'))
    img = handles.rectImg{1};
elseif(strcmpi(imgTarget, 'Rectified Image Chan 2'))
    if(handles.numRect ==2)
        img = handles.rectImg{2};
    else
        img = handles.rectImg{1};
    end
elseif(strcmpi(imgTarget, 'Final Image Chan 1'))
    img = handles.nonlinImg{1};
elseif(strcmpi(imgTarget, 'Final Image Chan 2'))
    if(handles.numRect ==2)
        img = handles.nonlinImg{2};
    else
        img = handles.nonlinImg{1};
    end
end  

%retrieve the hist range value.
histRange = eval(get(handles.histRange,'String'));

axes(handles.leftHist1Axes);
counts  = sum(histc(img(1:end,1:floor(end/2)),histRange),2);
bar(histRange,counts,'histc');
axesHistScale(handles);
axes(handles.rightHist1Axes);
counts  = sum(histc(img(1:end,ceil(end/2):end),histRange),2);
bar(histRange,counts,'histc');
axesHistScale(handles);

drawnow;


function range = getAutoRange(img, str)

if(strcmpi(str,''))
    vect = reshape(img,size(img,1)*size(img,2),1);
    hi = prctile(vect, 80);
    lo = prctile(vect, 20);
    diff = hi - lo;
    hi = hi + diff*.2;
    lo = lo - diff*.2;
    range = [lo,hi];
else
    range = eval(str);
end