% plotMatch.m
% Plots the results of SURF matching.

clc;

% Load data
indExt = strfind(SURFMatchMAT, '.mat');
matchData1to10 = load(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), 1, 10));
matchData11to20 = load(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), 11, 20));
matchData21to30 = load(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), 21, 30));
matchData31to40 = load(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), 31, 40));
matchData41to50 = load(sprintf('%s-%d-%d.mat', SURFMatchMAT(1:indExt-1), 41, 50));

% Parse data
if ~exist('queryFilenames', 'var')
    load(SURFQueryMAT);
end
if ~exist('databaseFilenames', 'var')
    load(SURFDatabaseMAT);
end
numImagesDB = length(databaseFilenames);
numImages = length(queryFilenames);
matchTopN = matchData1to10.matchTopN;
matchTopNPostRANSACPoints = zeros(numImages, matchTopN);
matchTopNPostRANSACPoints(1:10,:) = matchData1to10.matchTopNPostRANSACPoints(1:10,:);
matchTopNPostRANSACPoints(11:20,:) = matchData11to20.matchTopNPostRANSACPoints(11:20,:);
matchTopNPostRANSACPoints(21:30,:) = matchData21to30.matchTopNPostRANSACPoints(21:30,:);
matchTopNPostRANSACPoints(31:40,:) = matchData31to40.matchTopNPostRANSACPoints(31:40,:);
matchTopNPostRANSACPoints(41:50,:) = matchData41to50.matchTopNPostRANSACPoints(41:50,:);

matchTopNPreRANSACPoints = zeros(numImages, matchTopN);
matchTopNPreRANSACPoints(1:10,:) = matchData1to10.matchTopNPreRANSACPoints(1:10,:);
matchTopNPreRANSACPoints(11:20,:) = matchData11to20.matchTopNPreRANSACPoints(11:20,:);
matchTopNPreRANSACPoints(21:30,:) = matchData21to30.matchTopNPreRANSACPoints(21:30,:);
matchTopNPreRANSACPoints(31:40,:) = matchData31to40.matchTopNPreRANSACPoints(31:40,:);
matchTopNPreRANSACPoints(41:50,:) = matchData41to50.matchTopNPreRANSACPoints(41:50,:);

matchDatabaseNumbers = zeros(numImages, matchTopN);
matchDatabaseNumbers(1:10, 1:matchTopN) = matchData1to10.matchDatabaseNumbers(1:10, 1:matchTopN);
matchDatabaseNumbers(11:20, 1:matchTopN) = matchData11to20.matchDatabaseNumbers(11:20, 1:matchTopN);
matchDatabaseNumbers(21:30, 1:matchTopN) = matchData21to30.matchDatabaseNumbers(21:30, 1:matchTopN);
matchDatabaseNumbers(31:40, 1:matchTopN) = matchData31to40.matchDatabaseNumbers(31:40, 1:matchTopN);
matchDatabaseNumbers(41:50, 1:matchTopN) = matchData41to50.matchDatabaseNumbers(41:50, 1:matchTopN);

matchDistances = zeros(numImages, numImagesDB);
matchDistances(1:10, 1:numImagesDB) = matchData1to10.matchDistances(1:10, 1:numImagesDB);
matchDistances(11:20, 1:numImagesDB) = matchData1to10.matchDistances(11:20, 1:numImagesDB);
matchDistances(21:30, 1:numImagesDB) = matchData1to10.matchDistances(21:30, 1:numImagesDB);
matchDistances(31:40, 1:numImagesDB) = matchData1to10.matchDistances(31:40, 1:numImagesDB);
matchDistances(41:50, 1:numImagesDB) = matchData1to10.matchDistances(41:50, 1:numImagesDB);

matchDistancesSorted = zeros(numImages, numImagesDB);
matchDistancesSorted(1:10, 1:numImagesDB) = matchData1to10.matchDistancesSorted(1:10, 1:numImagesDB);
matchDistancesSorted(11:20, 1:numImagesDB) = matchData1to10.matchDistancesSorted(11:20, 1:numImagesDB);
matchDistancesSorted(21:30, 1:numImagesDB) = matchData1to10.matchDistancesSorted(21:30, 1:numImagesDB);
matchDistancesSorted(31:40, 1:numImagesDB) = matchData1to10.matchDistancesSorted(31:40, 1:numImagesDB);
matchDistancesSorted(41:50, 1:numImagesDB) = matchData1to10.matchDistancesSorted(41:50, 1:numImagesDB);

% Find match result
matchResult = zeros(1, numImages);
maxPostRANSAC = zeros(1, numImages);
for nQuery = 1:numImages
    
    disp(sprintf('Checking image %d: %s ...', nQuery, queryToDatabaseFilenames{nQuery}));
   
    % Ground truth match
    trueName = [databaseDir queryToDatabaseFilenames{nQuery}];
    
    % No good post-RANSAC match
    if sum(matchTopNPostRANSACPoints(nQuery,:)) == 0
        matchResult(nQuery) = 0;
        
    % At least one good post-RANSAC match
    else
        [maxPostRANSAC(nQuery), maxPostRANSACIndex] = max(matchTopNPostRANSACPoints(nQuery,:));
        databaseIndex = matchDatabaseNumbers(nQuery, maxPostRANSACIndex);
        searchName = databaseFilenames{databaseIndex};
        matchResult(nQuery) = (strcmp(trueName, searchName) > 0);
    end % if
    
end % nQuery

% Plot match result
numImagesVec = 1:numImages;
indMatch = find(matchResult > 0);
indFailure = setdiff(numImagesVec, indMatch);
figure(1); clf;
subplot(2,1,1);
stem(numImagesVec(indMatch), matchResult(indMatch), 'b'); hold on;
stem(numImagesVec(indFailure), matchResult(indFailure), 'r');
xlabel('query image'); ylabel('success = 1, failure = 0');
title(sprintf('SURF'));
subplot(2,1,2);
stem(numImagesVec(indMatch), maxPostRANSAC(indMatch), 'b'); hold on;
stem(numImagesVec(indFailure), maxPostRANSAC(indFailure), 'r');
xlabel('query image'); ylabel('max post-RANSAC points');

% Loop over images
figure(2); clf;
plotFigures = 1;
for nQuery = 1:numImages
    
    disp(sprintf('Showing image %d ...', nQuery));
   
    if ~matchResult(nQuery) && plotFigures
        frame1 = queryFrames{nQuery};
        desc1 = queryDescriptors{nQuery};
        
        warning off; 
        showSURF(imresize(imreadbw(queryFilenames{nQuery}), [SURFInputHeight SURFInputWidth], 'bilinear'), frame1); 
        warning on;
        title(sprintf('Image %d: success(%d), features(%d)', ...
            nQuery, matchResult(nQuery), size(frame1,1)));
        pause;
        
    end
    
end % nQuery

% Save result
save(SURFMatchMAT, 'match*');