% matchQuery.m
% Match query images to top database candidates.

printTitle('Matching query images ...');

% Loop over all input images
if ~exist('queryFilenames', 'var')
    load(SURFQueryMAT);
end
numImages = length(queryFilenames);
if ~exist('databaseFilenames', 'var')
    load(SURFDatabaseMAT);
end
numImagesDB = length(databaseFilenames);
% Pre-RANSAC
matchDatabaseNumbers = zeros(numImages, numImagesDB); % closest match first
matchDistances = zeros(numImages, numImagesDB); 
matchDistancesSorted = zeros(numImages, numImagesDB); % smallest distance first
% Post-RANSAC
matchTopN = 20;
matchTopNPreRANSACPoints = zeros(numImages, matchTopN);
matchTopNPostRANSACPoints = zeros(numImages, matchTopN);
maxNumFeatures = 3000;
for nImage = startNum:endNum
    
    disp(sprintf('\nProcessing image %d/%d ... \n', nImage, numImages));
    
    % Choose query image parameters
    frame1 = queryFrames{nImage};
    desc1 = queryDescriptors{nImage};
    file1 = queryFilenames{nImage};    
    disp(sprintf('features: %d', size(frame1,1)));
    
    % Loop over all database images
    for nImageDB = 1:numImagesDB
        
        disp(sprintf('Comparing image %d/%d ... ', nImageDB, numImagesDB));
        
        frame2 = databaseFrames{nImageDB};
        desc2 = databaseDescriptors{nImageDB};
        matchDistances(nImage, nImageDB) = ratioTest(desc1, desc2);
        
        disp(sprintf('features: %d', size(frame2,1)));
        disp(sprintf('Ratio test matches: %d', matchDistances(nImage, nImageDB)));
        
        clear frame2 desc2;
        
    end % nImageDB
    [matchDistancesSorted(nImage,1:numImagesDB), matchDatabaseNumbers(nImage,1:numImagesDB)] = sort(matchDistances(nImage,1:numImagesDB), 'descend');
    
    % Perform ANN, ratio test, RANSAC between query and top N matches
    for nMatch = 1:matchTopN
        
        disp(sprintf('Checking top match %d ...', nMatch));
        
        nImageDB = matchDatabaseNumbers(nImage, nMatch);
        frame2 = databaseFrames{nImageDB};
        desc2 = databaseDescriptors{nImageDB};
        file2 = databaseFilenames{nImageDB};
        [flag, matchTopNPreRANSACPoints(nImage,nMatch), matchTopNPostRANSACPoints(nImage,nMatch)] = ...
            SURFPairwiseMatchFeatureSets(frame1, desc1, file1, frame2, desc2, file2, 'euclidean', 0);
        
        clear frame2 desc2;
        
    end % nMatch
    
    clear desc1 file1;
    
    pause(3);
    
end % nImage

% Save result
indExt = strfind(SURFMatchMAT, '.mat');
save(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), startNum, endNum), 'match*');