%                                 processregion.m
%
%                     By: Henry Chang and Ulises Robles

% ---------------------------------------------------------------------
% Given a image with only one region on it, determine if this region
% suggests a face or not. If so, we return a rectangle coordinate that
% will be drawn to indicate a detected face. 
% Arguments: 
%    imsourcegray: the original image in grayscale.
%    bwsegment: the black and white image with the desired region on it
%    numholes: the number of black areas inside the region
%    frontalmodel: the grayscale image of our frontal face model
%
% ----------------------------------------------------------------------


function [RectCoord, imsourcegray] = processregion(imsourcegray, bwsegment, numholes, ...
				     frontalmodel)

  RectCoord = -1;
  % Get the size of the image
  [m n] = size(bwsegment);
   
  % Get the center of mass (energy) of the image
  [cx,cy]=center(bwsegment);
  
  % Fill the holes in the binary image
  bwnohole=bwfill(bwsegment,'holes');
  
  % To get just the probable face from the image
  justface = uint8(double(bwnohole) .* double(imsourcegray));
  
  % Get the angle of rotation
  angle = orient(bwsegment,cx,cy);
  
  % This is to compute the width and height of the region
  bw = imrotate(bwsegment, angle, 'bilinear');
  bw = bwfill(bw,'holes');
  [l,r,u,d] = recsize(bw);
  wx = (r - l +1);  % width
  ly = (d - u + 1); % height
  
  % Get the ration between the height (ly) and width(wx) of the region
  wratio = ly/wx   
 
  % To be used if we find regions that are very tall
  % Adjust the ratio by reducing the height of the region
    if (wratio > 1.6) 

      ly = floor(1.5 * wx);    % approx. computation of the new height
      
      % This is to eliminate the parts of the image that are cut 
      % after computing the new height of the region
      [l,r,u,d] = recsize(bwnohole);
      start = floor((u+ly)*cos(-angle*pi/180));
      for i=start:m,
         for j=1:n,  
           bwsegment(i,j) = 0;
         end
      end
      
      % Compute the coordinates of the center of the new region
      [cx,cy]=center(bwsegment);
      
      % Get the new ratio
      wratio = ly/wx;   
    end;
   
  
 % We will determine the cross-correlation value between the image region
 % that might indicate a face and the face model if the number of holes
 % is greater than one. The ratio > 0.8 condition avoids the problem of
 % dealing with regions that are too wide.
  
  if (numholes >=1  &  wratio >= 0.8) 
    [ccorr,mfit, RectCoord] = faceInfo(justface,frontalmodel,ly,wx, cx,cy, angle);
   else ccorr = 0;
  end;
   
  
 % ****************************************************************** 
 % Do the following only if we claim that we have found a face.
 % *****************************************************************

 % If we have holes, and the result of the cross-correlation above 1.6,
 % this is a face region.
 
 if (ccorr > 0.6 & numholes >= 1)  
   
   % Get an image with a black whole in the region where the face model
   % is. (Get the quantized version of the face model)
   mfitbw = (mfit >=1);
  
   % Flip the values of the image, so we can have white areas. This
   % areas will be multiplied by the original image. The remainding 
   % black "hole" is to be added by the face model.
   invbw = xor(mfitbw,ones(size(mfitbw)));
   
   % Multiply the above image by the original one
   source_with_hole = uint8(double(invbw) .* double(imsourcegray));
    
   % Add the rotated model face.
   
   % This image contains the original image part that is not the face
   % and the model face added.
   final_image = uint8(double(source_with_hole) + double(mfit));
   
   figure;
   imshow(final_image);
  
   imsourcegray = final_image;
 end;
 
 
 
