function [sampledGTData, indices] = sampleGroundTruthObjectsFromLidarData(trainingData,classNames,varargin)   
    [threshold,filePath] = iParseInputs(classNames,varargin{:});                        
    threshold = threshold.*cast(ones(1,numel(classNames)),class(threshold));
    
    % Create the directory
    if(~exist(filePath,'dir'))
        mkdir(filePath)
    end                             
    numFiles = size(trainingData.UnderlyingDatastores{1,1}.Files,1);
    boxLabel = [];
    boxCategory = {};
    allFilesName = {};
    count = 0;            
    reset(trainingData);  
    for i = 1:numFiles     
        pcLabel = read(trainingData);        
        pc = removeInvalidPoints(pcLabel{1,1});
        allboxLabels = pcLabel{1,2};
        categoricalLabels = pcLabel{1,3};          
        for j = 1:numel(classNames)   
            labels = allboxLabels(categoricalLabels==classNames{j},:);    
            
            % Calculating the number of points inside an object
            numPoints = arrayfun(@(x)(findPointsInsideCuboid(cuboidModel(labels(x,:)),pc)),...
                                (1:size(labels,1)).','UniformOutput',false);
            
            % Filtering objects with respect to MinPoints
            posIndex = cellfun(@(x)(length(x) > threshold(j)), numPoints);            
            labels = num2cell(labels(posIndex,:),2);
            loc = cat(2,pc.Location,pc.Intensity);
            lidarPt = cellfun(@(x)(loc(x,:)),numPoints(posIndex),'UniformOutput',false);                       
            boxLabel = [boxLabel;labels];
            
            % Storing sampled objects at the specified folder
            for k=1:size(lidarPt,1)
                count = count+1;
                lidarPoints = lidarPt{k,1};
                fname = fullfile(filePath,sprintf('%010d.mat',count));
                save(fname,'lidarPoints');
                allFilesName{end+1,1} = fname;
                boxCategory{end+1,1} = cellstr(classNames{j});
            end
        end        
    end          
   finalBoxLabels = table(boxLabel,boxCategory);
   blds = boxLabelDatastore(finalBoxLabels);        
   sampleDs = fileDatastore(allFilesName,'ReadFcn',@load);
   sampledGTData = combine(sampleDs,blds);
   indices = string(boxCategory);
end   
            
            
function [threshold, filePath] = iParseInputs(classNames,varargin)
p = inputParser();
defaultMinPoints = zeros(numel(classNames),1);
defaultsampleLocation = fullfile(tempdir,'GTDataAug');
addOptional(p,'MinPoints', defaultMinPoints, @validateMinPoints);
addOptional(p,'sampleLocation',defaultsampleLocation);
parse(p,varargin{:}) 
threshold = p.Results.MinPoints;
filePath = p.Results.sampleLocation;
end

function validateMinPoints(x)
validateattributes(x, {'numeric'}, {'integer','nonnegative','real'}); 
end