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

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

% Last Modified by GUIDE v2.5 29-Sep-2010 18:23:41

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

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

% Load test image
img = double(imread('Building2.bmp'));
img = img(1:512, 1:640, :);
[nx ny ncolors] = size(img);
handles.img = img;
handles.ncolors = ncolors;

% Add noise
SNR = 10;
sigpow = mean(abs(img(:)).^2);
stdnois = sqrt(10^(-SNR/10)*sigpow);
nois = randn(nx, ny, ncolors)*stdnois;
data = img + nois;
handles.data = data;

% Display data in axes 1
axes(handles.axes1); cla;
image(uint8(data)); axis equal; axis off;

% Wavelet denoising parameters
handles.wname = 'haar';
handles.nlev = 5;
handles.lam = 512;
set(handles.text1, 'String', cat(2, 'Cut-off: ', num2str(handles.lam)));
set(handles.slider1, 'Value', log2(handles.lam));

% Update handles structure
guidata(hObject, handles);

% Show estimate at initiation
wavedenois(handles);


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


% --- Outputs from this function are returned to the command line.
function varargout = denoisExample_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 slider movement.
function slider1_Callback(hObject, eventdata, handles)
% hObject    handle to slider1 (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

set(handles.text1, 'String', 'Processing...');

lam = get(hObject, 'Value');
lam = 2.^lam;
handles.lam = lam;

% Update handles structure
guidata(hObject, handles);

% Run wavelet denoising
wavedenois(handles);
set(handles.text1, 'String', cat(2, 'Cut-off: ', num2str(lam)));

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider1 (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


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

set(handles.text1, 'String', 'Processing...');

% Read variabels from handles structure
lam = 72; 
set(handles.slider1, 'Value', log2(lam));
handles.lam = lam;

% Update handles structure
guidata(hObject, handles);

% Run wavelet denoising
wavedenois(handles);
set(handles.text1, 'String', cat(2, 'Cut-off: ', num2str(lam)));


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

% --- Execute wavelet denosing by soft-thresholding and display image
function wavedenois(handles)
data = handles.data;
wname = handles.wname;
nlev = handles.nlev;
lam = handles.lam;
ncolors = handles.ncolors;

for ii = 1:ncolors
    % Wavelet decomposition
    % [c, s] = wavedec2(data(:, :, ii), nlev, wname);
    swc = swt2(data(:, :, ii), nlev, wname);
    [wx wy wz] = size(swc);
    
    % Soft thresholding
    % cdet = wthresh(c(prod(s(1,:))+1:end), 's', lam);
    % c = [c(1:prod(s(1,:))) cdet];
    for jj = 1:wz-1
        swcdet(:, :, jj) = wthresh(swc(:, :, jj), 's', lam);
    end
    swc = cat(3, swcdet, swc(:, :, wz));
    
    % Wavelet reconstruction
    % estimate(:, :, ii) = waverec2(c, s, wname);
    estimate(:, :, ii) = iswt2(swc, wname);
end

% Display estimate in axes 2
axes(handles.axes2); cla;
image(uint8(estimate)); axis equal; axis off;
