
%% Standard Image Lens Correction
%
%Corrects for lens distortion in a provided image sequence.
%


%% Input Arguments

% seqName - Image sequence name.
%           String.

% seqOutName - Output image sequence name.
%              String.

% coefs - Standard lens correction model coefficients.
%         8x1 vector.

% dirPath - Optional parent directory path (relative userpath) to image sequence.
%           String (default: '.')

% dirOutPath - Optional parent directory path for output image sequence.
%              String (default: '.');

% type - Optional image type specifier
%        String { 'jpg', 'ppm', default: <same as input>}

% side - Optional side of image.
%        String {'left','right', default: 'all'}.


%% Output Arguments

%VOID


%% Standard Lens Correction

function standard_image_lens_correction(seqName, seqOutName, coefs, varargin)

%parse input parameters
[coefs, fileInNames, fileOutNames, side, nImgs, ~, nCols, scale, offset] = input_parser(seqName, seqOutName, coefs, varargin{:});

for i = 1:nImgs,
    
    imgIn  = imread(fileInNames{i});
    
    if strcmp(side,'right')
        
        imgIn = imgIn(:, ceil(nCols/2):end, :);
        
    elseif strcmp(side,'left')
        
        imgIn = imgIn(:, 1:floor(nCols/2), :);
        
    end            
    
    imgOut = standard_lens_correction_c(double(imgIn), coefs, scale, offset);
    imwrite(uint8(imgOut), fileOutNames{i});
    
end

end %end of blind lens correction


%% Input Parser

function [coefs, fileInNames, fileOutNames, side, nImgs, nRows, nCols, scale, offset] = input_parser(seqName, seqOutName, coefs, varargin)


%add library for 'natural' sorting of strings with numeric components
matlabDir = userpath;
matlabDir = matlabDir(1:end-1);
addpath(strcat(matlabDir,'/MASC/External Tools/SortNat'));

% parse input arguments
p = inputParser;
p.addRequired('seqName', @(x) ischar(x));
p.addRequired('seqOutName', @(x) ischar(x));
p.addRequired('coefs', @(x) ...
              validateattributes(x,{'numeric'},{'real','nonnan','vector','finite'}));
p.addParameter('dirPath', '', @(x) ischar(x));
p.addParameter('dirOutPath', '', @(x) ischar(x));
p.addParameter('type', '', @(x) ...
                ischar(validatestring(x, {'jpg','ppm'})));
p.addParameter('side', 'all', @(x) ismember(x, {'left','right','all'}));
p.addParameter('scale', [], @(x) ...
              validateattributes(x,{'numeric'},{'real', 'nonnan', 'vector', 'positive', 'finite', 'nrows', 2}));
p.addParameter('offset', [1/2; 1/2], @(x) ...
              validateattributes(x,{'numeric'},{'real', 'nonnan', 'vector', 'finite', 'nrows', 2}));
          
p.parse(seqName, seqOutName, coefs, varargin{:});
inputs           = p.Results;
seqName          = inputs.seqName;
seqOutName       = inputs.seqOutName;
coefs            = inputs.coefs;
dirPath          = inputs.dirPath;
dirOutPath       = inputs.dirOutPath;
type             = inputs.type;
side             = inputs.side;
scale            = inputs.scale;
offset           = inputs.offset;

matlabDir = userpath;
matlabDir = matlabDir(1:end-1);

if isempty(dirPath)
    fullDirPath = '.';
else
    if regexp(dirPath, matlabDir)
        fullDirPath = dirPath;
    elseif strncmpi(dirPath, '.', 1)
        fullDirPath = dirPath;
    else
        fullDirPath = fullfile(matlabDir, dirPath);
    end
end

if isempty(dirOutPath)
    fullDirOutPath = '.';
else
    if regexp(dirOutPath, matlabDir)
        fullDirOutPath = dirOutPath;
    elseif strncmpi(dirOutPath, '.', 1)
        fullDirOutPath = dirOutPath;
    else
        fullDirOutPath = fullfile(matlabDir, dirOutPath);
    end
end

%check input image sequence name exists
seqPath         = fullfile(fullDirPath, strcat(seqName,'*'));
dirStruct       = dir(seqPath);
imgSeqFileNames = {dirStruct.name};

if isempty(imgSeqFileNames)
    error('Image sequence cannot be found at %s', fullDirPath)
end

%create array of absolute path names for all files
nImgs     = size(imgSeqFileNames, 2);
fileInNames = cell(nImgs,1);
for i = 1:nImgs,
    fileInNames{i} = fullfile(fullDirPath, imgSeqFileNames{i});
end

%natural-order sorting of file names 
fileInNames = sort_nat(fileInNames, 'ascend');

[~, ~, ext] = fileparts(fileInNames{1});

if ~isempty(type)   
   ext = strcat('.',type); 
end

%create array of absolute path names for all output files
fileOutNames = cell(nImgs, 1);
if nImgs == 1
    fileOutNames{1} = fullfile(fullDirOutPath, strcat(seqOutName, ext));
else
    for i = 1:nImgs,
        fileOutNames{i} = fullfile(fullDirOutPath, strcat(seqOutName, num2str(i-1), ext));
    end
end

firstImg = imread(fileInNames{1});
[nRows, nCols, ~] = size(firstImg);

if isempty(scale)
    scale = [nCols; nRows];
end

end
