% Created by: Dima Al Damen
% July 1st 2007
% Last updated August 2007

% This function returns a normalized template of the person walking across
% a sequence after edge correlating. Notice that the normalization is done
% after creating the template so it anticipates the person to walk without
% much change of depth along the sequence.

% Note: after creating the template, the difference between the mean
% template and each image is calculated, then a specified threshold
% percentage of the images were used to re-calculate a better average. This
% is one way to get rid of the noise and very inconsistent images in
% creating the template. This technique proved less blury images are being
% created.

% Note: the normalization was commented at a later stage

% inputs: beginningFileName: the starting string of the images
%         beginningFrame: the starting frame number
%         endFrame: the ending frame number

% outputs: - normalizedTemplate: normalized template by the specified width
% and height in the parameters.

% uses functions: - findMedianFile
%                 - cleanBlob
%                 - normalizeImage

% note: this is to be updated to benefit from the already created and
% centred images

function [normalizedTemplate, newMedianFile, centredImages, foundFrames, footLoc] = getNormalizedPersonTemplate_f (beginningFileName, setNo, beginningFrame, endFrame, bbFile, rescaleFactor, params)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% getNormalizedPersonTemplate_f
% Syntax:
%   [normalizedTemplate, newMedianFile, centredImages, foundFrames, footLoc] = getNormalizedPersonTemplate_f (beginningFileName, setNo, beginningFrame, endFrame, bbFile, rescaleFactor, params)
%
% Input:
%   beginningFileName: The path to the images
%   setNo: number of set
%   beginningFrame: first frame of the trajectory
%   endFrame: last frame of the trajectory
%   bbFile: bounding boxes across the trajectory
%   rescaleFactor: rescaling the frames to a fixed frame size
%   params: the selected parameter values
%
% Output:
%   normalizedTemplate: the temporal template in a specified frame size
%   newMedianFile: ICP-aligned median positioning of the foreground images
%   centredImages: The aligned and centred foreground images
%   foundFrames: The frames at which the person was tracked
%   footLoc: The foot position throughout the trajectories
%
% Descrioption:
%   Creates the temporal template for a trajectory
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   personWidth = params.Results.personWidth;
   personHeight = params.Results.personHeight;
   topValue = params.Results.topValue;
   backgroundColour = params.Results.backgroundColour;
   writeIntermediateResults = params.Results.writeIntermediateResults;
   imgtype = params.Results.imgtype;
      
   [newMedianFile, footLoc] = edgeCorrelationICP_f (setNo, beginningFrame, endFrame, bbFile, strcat (beginningFileName, '_ICPMedians.dat'), rescaleFactor, params);

   % first loop, calculate the average
   fullWeight = zeros (personHeight, personWidth);
   count = 0;
   frameWidth = -1;
   centredImages = zeros (personHeight, personWidth, (endFrame-beginningFrame+1));
   foundFrames = [];
   for i=beginningFrame:endFrame
       [rowNo, n] = find (newMedianFile(:,1) == i);
       fileName = strcat ('Set', num2str(setNo), '\', num2str (i), '.', imgtype);
       if (exist (fileName, 'file'))
          img = imread (fileName);
          if (frameWidth == -1)
            [frameHeight, frameWidth] = size (img);
          end;
          if (backgroundColour == 0)
             img = cleanBlob(img);
          else
             img = invertAndCleanBlob (img);
          end;
          [m,n] = find (bbFile(:,1) == i);
          if (size(m,1) == 0)
              continue;
          end;
          img = maskAndResize (img, bbFile(m,2:5), rescaleFactor);
          count = count + 1;
          foundFrames = [foundFrames; i];
          centredImages (:,:,count) = centreAroundMedian (img, newMedianFile(rowNo, 4), newMedianFile(rowNo, 5), personWidth, personHeight);
          fullWeight = fullWeight + centredImages(:,:,count);
         % figure; imshow (fullWeight);
       end;
   end;
   % averages by number of frames
   fullWeight = fullWeight / count;
   normalizedTemplate = fullWeight;
   
   % second phase, calculate the difference between each frame and the
   % template created. This is placed into a matrix with two columns, the
   % frame number and the difference
   differenceMatrix = zeros (0, 2);
   for i=1:count
       diffBwImgAndMean = sum(sum(abs(centredImages(:,:,i)-normalizedTemplate)));
       newRow = [i, diffBwImgAndMean];
       differenceMatrix = [differenceMatrix; newRow];
   end
   
   % decides on the top percentile values of the difference matrix
   PctileMatrix = prctile (differenceMatrix, topValue);
   
   % finds all frame numbers that exceed that percentile value
   [m,n] = find (differenceMatrix(:,2) < PctileMatrix (1,2));
   
   % re-calculates the template
   fullWeight2 = zeros (personHeight, personWidth);
   count2 = 0;
   for i = differenceMatrix(m,1)'
       count2 = count2 + 1;
       fullWeight2 = fullWeight2 + centredImages(:,:,i);
   end
   fullWeight2 = fullWeight2 / count2;
   normalizedTemplate = fullWeight2;

   % stores the template to be referred to later
   if (writeIntermediateResults == true)
       imwrite (normalizedTemplate, strcat (beginningFileName, '_personTemplate.jpg'));
   end;
end