
%% Full-Set (Combine Line-Points) Validation Trials of Lens Distortion Correction Methods (Script)
%
% Runs full set validation tests on lens distortion methods: proposed (blind),
% standard (inverse-transform), and Alvarez et al.
%
% The lens distortion correction parameters are learnt on a complete/full 
% set of calibration harp images, the correcting capability of the learnt
% parameters is applied to all images in set.
%


%% Script Setup 

addpath('./common/');

close all;
clc;

rng(0);


%% Find Support Line-Point Files 

linePath   = './line_points/';
errPath   = './error_analysis/';
coefsPath = './coefs/';
suppFiles = {'mat'};
filter = 'manip'; %require manip prefix to diff. b/w single and fullset line points

% Find all supported files within directory
fprintf('\tSearching directory %s...\n', linePath);
[matNames, nMats] = find_supported_files(linePath, suppFiles, filter);
fprintf('\t\tFound %d line-point .mat files\n', nMats);


%% Select Files for Full-Set Validation

% Decide whether to manually specify line point .mat files used, or to
%have program automatically segment files into 'camera-model' groups and
%have user choose specific camera model ('single-only-selection')

[selectMatNames, selectCamModel] = select_files(matNames, '^manip_(?<group>[a-zA-Z0-9-]+)');


%% Combine Selected Line Points

fprintf('Combining line points...');
[pts, lineSizeMat, scale, offset] = combine_line_points( linePath, '', '', 'fileNames', selectMatNames);

fullsetName = sprintf('%s_%s', 'fullset', selectCamModel);
saveFileName = sprintf('%s.mat', fullsetName);
save(fullfile(linePath, saveFileName), 'pts', 'lineSizeMat', 'scale', 'offset');
fprintf('done\n');
    

%% Compute Lens Distortion Model Parameters/Coefficients 

methodPaths = {'../standard_lens_calibration_c/', '../blind_lens_calibration_c/', '../alvarez_image_lens_correction_c/'};
methods = {'std','blind','alvarez'};
models = {'std', 'std', 'rad'};
nMethods = length(methods);

tol = 1e-6;
nMaxIter = 5000;

for m = 1:nMethods,
    
    method = methods{m};            
       
    loadFileName = sprintf('%s.mat', fullsetName);
    load(fullfile(linePath, loadFileName), 'pts', 'lineSizeMat', 'scale', 'offset');                
    saveFileName = sprintf('%s_%s.mat', method, fullsetName);
    
    switch(method)                        

        case 'std'

            cd(methodPaths{m});
            [coefs, corrPts, err] = standard_lens_calibration_c(pts, lineSizeMat, [], tol, nMaxIter);                                           

        case 'blind'

            cd(methodPaths{m});
            [corrPts, coefs, err] = blind_lens_calibration(pts, lineSizeMat, 'maxIter', nMaxIter);                            

        case 'alvarez'

            cd(methodPaths{m});
            [coefs, err] = alvarez_image_lens_correction('pts', pts, 'lineSizeMat', lineSizeMat, 'optimizeCenter', 1);                                                           
            coefs = coefs{1};
                                                       
        otherwise
            error('FullsetValidation:InvalidMethod', 'Unknown method specified');

    end

    cd ../test_environment/;
    save(fullfile(coefsPath, saveFileName), 'coefs', 'scale', 'offset');
    
end


%% Compute Full-set Validation Error Tables

for m = 1:nMethods,
       
   nMatFiles = length(selectMatNames); 
   errTable = nan(1, nMatFiles);  
         
   method = methods{m};
   loadFileName = sprintf('%s_%s.mat', method, fullsetName);
   load(fullfile(coefsPath, loadFileName), 'coefs', 'scale', 'offset');  
    
   coefsScale = scale;
   coefsOffset = offset;
   
   for p = 1:nMatFiles,                                        

       load(fullfile(linePath, selectMatNames{p}), 'pts', 'lineSizeMat', 'scale', 'offset'); 
       
       if ~isequal(scale, coefsScale)
           error('CrossValidation:IncompatibleNorm', 'Line points were normalized differently then coefficient-learning');
       end

       if ~isequal(offset, coefsOffset)
           nPts = size(pts, 1);
           pts(:,1) = pts(:,1) - (coefsOffset(1) - offset(1))*ones(nPts, 1);
           pts(:,2) = pts(:,2) - (coefsOffset(2) - offset(2))*ones(nPts, 1);    
       end

       [err, res] = plumb_line_cost_function(pts, lineSizeMat, coefs, 'methodType', method, 'modelType', models{m});
       errTable(p) = err/sqrt(length(res));

   end   
   
   saveErrFileName = sprintf('rmse_%s_%s', method, fullsetName);
   save(fullfile(errPath, saveErrFileName), 'errTable');
    
end






















