function args=parse_inputs(varargin)
% iptchecknargin(3,Inf,nargin,mfilename);
narginchk(2,Inf)
%% default value
args.input_image          =  varargin{1};
args.initial_points       =  varargin{2};
args.initial_tfm_matrix   =  eye(3);
args.tol                  =  1e-7;
args.outer_tol            =  1e-4;
args.outer_max_iter       =  1;
args.outer_display_period =  1;
args.inner_tol            =  1e-4;
args.inner_c              =  1;
args.inner_alpha          =  [];
args.inner_display_period =  100;
args.inner_max_iter       =  8;

args.blur                 =  1;
args.pyramid              =  1;
args.branch               =  1;
args.patsize              =  51; % the size of the patch
args.step                 =  floor((args.patsize)/2)+1; % the step between each keypatch
args.focus_threshold      =  50; % when doing pyramid the smallest focus_edge we can tolerate.
args.outer_tol_step       =  10; % as resolution goes high how relaxed should the outer_tol be.
args.blur_kernel_size_k   =  2;  % neighbourhood scalar for the size of the blur kernel.
args.blur_kernel_sigma_k  =  2;  % standard derivation scalar for blur kernel.
args.pyramid_max_level    =  2;  % number of pyramid levels we want to act on.
args.branch_max_iter      =  10; % in each branch, how much iteration we take.
args.branch_accuracy      =  10;  % higher means smaller step-width.
args.display_result       =  1;
args.focus_size           =  [];
args.branch_max_rotation  =  pi/6;
args.branch_max_skew      =  0.7; % purely empirical, just to emphasize that in affine mode, the skew should be smaller...

args.inner_patsize        =  8;
args.inner_step           =  floor((args.inner_patsize)/2)+1;
args.inner_patnum         =  30;
args.inner_SearchWin      =  floor((args.patsize)/2)+1;
args.nSig                 =  7;
args.inner_delta          =  0.01;
args.c                    =  sqrt(2); 
args.Innerloop_B          =  10; 
args.Innerloop_X          =  100;  

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Regularization parameter
args.kappa                =    2;    args.tau        =  70;        % regularzation parameter for offset(nuclear norm)
args.rho                  =    100;  args.gamma      =  0.1;       % regularzation parameter for sparse dictionary
args.lambda_1             =    330;  args.belta_1    =  10;        % regularzation parameter for local directional smoothness
args.lambda_2             =    2000; args.belta_2    =  100;       % regularzation parameter for local directional preservation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

for i=4:2:nargin
    switch(lower(varargin{i}))
        case 'outer_tol'
            args.outer_tol=varargin{i+1};
        case 'outer_maxiter'
            args.outer_max_iter=varargin{i+1};
        case 'outer_display'
            args.outer_display_period=varargin{i+1};
        case 'inner_tol'
            args.inner_tol=varargin{i+1};
        case 'inner_mu'
            args.inner_mu=varargin{i+1};
        case 'inner_display'
            args.inner_display_period=varargin{i+1};
        case 'inner_maxiter'
            args.inner_max_iter=varargin{i+1};
        case 'inner_c'
            args.inner_c=varargin{i+1};
        case 'blur'
            args.blur=varargin{i+1};
        case 'pyramid'
            args.pyramid=varargin{i+1};
        case 'branch'
            args.branch=varargin{i+1};
        case 'focus_thre'
            args.focus_threshold=varargin{i+1};
        case 'outer_tol_step'
            args.outer_tol_step=varargin{i+1};
        case 'blur_sigma'
            args.blur_kernel_sigma_k=varargin{i+1};
        case 'blur_neighbor'
            args.blur_kernel_size_k=varargin{i+1};
        case 'pyramid_maxlevel'
            args.pyramid_max_level=varargin{i+1};
        case 'branch_maxiter'
            args.branch_max_iter=varargin{i+1};
        case 'branch_accuracy'
            args.branch_accuracy=varargin{i+1};
        case 'no_translation'
            args.no_translation=varargin{i+1};
        case 'initial_matrix'
            args.initial_tfm_matrix=varargin{i+1};
        case 'display_inter'
            args.display_result=varargin{i+1};
        case 'initial_points'
            args.initial_points=varargin{i+1};
        case 'focus_size'
            args.focus_size=floor(varargin{i+1});
        case 'save_path'
            args.save_path=varargin{i+1};
        case 'branch_max_rotation'
            args.branch_max_rotation=varargin{i+1};
        case 'branch_max_skew'
            args.branch_max_skew=varargin{i+1};
    end
end

%% do some initialization
if size(args.initial_points, 2)==2
    args.initial_points=floor(args.initial_points);
    args.focus_size=[args.initial_points(2, 2)-args.initial_points(2, 1)+1 args.initial_points(1, 2)-args.initial_points(1, 1)+1];
    args.center=floor(mean(args.initial_points, 2));
elseif size(args.initial_points, 2)==4
    args.center=floor(mean(args.initial_points, 2));
    pt_mean=args.initial_points-args.center*ones(1, 4);
    if isempty(args.focus_size)
        args.focus_size=mean(abs(pt_mean), 2)*2;
        args.focus_size=floor([args.focus_size(2) args.focus_size(1)]);
    end
    focus_center=floor([1+args.focus_size(2) 1+args.focus_size(1)]/2);
    XData=[1-focus_center(1) args.focus_size(2)-focus_center(1)];
    YData=[1-focus_center(2) args.focus_size(1)-focus_center(2)];
    X=[XData(1) XData(2) XData(2) XData(1);...
       YData(1) YData(1) YData(2) YData(2)];
    args.initial_tfm_matrix=compute_homography(X, floor(pt_mean));
end