function [Results,Guess,CLab,Correct_size,CLabsum,meatdif,CLabsumMeat,CLabsumMax,newI]=findface(filename)
% This function finds all the faces in the image named 'filename'
% It returns:
% 'Results' coordinates of the center of the faces.
% 'Guess' First raw estimate of the faces positions, may includes several targets per face.
% 'CLab' 3D matrix with all the correlations with all the templates.
% 'Correct_size' Vector containing the height that was used for each template.
% 'CLabsum' Sum of all the correlations with all the templates.
% 'meatdif' Distance from each point to the average color of the templates.
% 'CLabsumMeat' Result of adding the sum of all the correlations, with an estimate of where there is flesh color.
% 'CLabsumMax' Processed CLabsumMeat in which only the local maxima are present.
% 'newI' RGB image with green squares around the faces.

%Only the peaks over my_threshold with respect to the absolut maxima are
%taken into account.
my_threshold=0.7;

%Absolut threshold for face existence
my_face_threshold=12;

%meat_factor specifies the maximum value that will be added or substracted
%in the places with or without flesh color.
meat_factor=2;

%meat_threshold is the sigmoid parameter that determines whether if a point
%is close to flesh color or not.
meat_threshold=15;
bar=waitbar(0,'Loading image');

%First we load the image and resize it so that its maximum dimension is
%800.
Irgb=image_resize(filename,800);

%Get the size (we do not know which dimension has been resized) and convert
%to Lab
[imx,imy,imz]=size(Irgb);
M=makecform('srgb2lab');
I=applycform(Irgb,M);
waitbar(0,bar,'Looking for the correct size');

%Load the template names.
template_names=dir('../caras/*.jpg');

CLab=zeros(imx,imy,length(template_names));
Correct_size=zeros(length(template_names),1);

sizes=[400;365;330;295;260;225;190;155;120;85;50];

%With the first template, we try all sizes and we assume that the correct
%size is the one that produces the highest correlation value.
[Correct_size(1),maximum,CLab(:,:,1)]=trysizes(I,template_names(1).name,M,sizes);

for k=2:length(template_names)
    waitbar(k/length(template_names),bar,'Comparing faces')
    
    %In each template we take the average of the previous sizes and try the
    %correlation with the one closest to the average, the one inmidiately
    %higher and the one inmideately lower.
    sizes=give_sizes(Correct_size);
    
    %Calculate correlations values.
    [Correct_size(k),maximum,CLab(:,:,k)]=trysizes(I,template_names(k).name,M,sizes);
end
close(bar)

%Sum all correlations
CLabsum=sum(CLab,3);

%This functions loads all the templates, averages the (a,b) values in all
%of them and also averages between them, providing the two averages.

[m1,m2]=calculate_mean;

%We calculate the distance in (a,b) coordinates from each point to the
%calculated averages.

meatdif=sqrt((double(I(:,:,2))-m1).^2+(double(I(:,:,3))-m2).^2);

%Now we pass that difference through a sigmoid that will determine if the
%color is close enough to be considered flesh (in which case the value is
%meat_factor) or not (in which case the value is -meat_factor). If the
%distance is smaller than meat_threshold then it is considered flesh.

meat=2*meat_factor.*sigmf(meatdif,[-1 meat_threshold])-meat_factor;

%We add that matrix to the calculated correlations.

CLabsumMeat=CLabsum+meat;

%Look if there is any face in the picture
if (max(max(CLabsumMeat))<my_face_threshold)
    sprintf('No face found in the picture')
    %This indicates how to draw the result images.
    noface=1;
else
    noface=0;
end

    CLabsumMeat2=CLabsumMeat;

    %To eliminate undesired local maxima we make zero all those points that are
    %lower than 70% of the highest peak.

    CLabsumMeat2(find(CLabsumMeat2<(my_threshold.*max(max(CLabsumMeat2)))))=zeros(size(CLabsumMeat2(find(CLabsumMeat2<(my_threshold.*max(max(CLabsumMeat2)))))));

    %We calculate the local maxima among those points that were above the
    %threshold, which gives us a series of peaks.

    CLabsumMax=(CLabsumMeat2.*localmax(CLabsumMeat2))./max(max(CLabsumMeat2));

    %These peaks are the first guess of face coordinates.

    [X,Y]=ind2sub(size(CLabsumMax),find(CLabsumMax>0));
    Z=CLabsumMax(find(CLabsumMax>0));

    Guess=[Z,X,Y];
    Guess=sortrows(Guess,-1);

    %Tipically several peaks appear in each face due to the differences between
    %the templates and the effect of the flesh function. For this reason, those
    %peaks that are in a diameter 40% bigger the average template size are
    %considered to be the same face. This 40% accounts for the fact that the
    %templates do not include the whole head, and that we do not know where the
    %center of the face is exactly.

    Results=my_clusters2(Guess,Correct_size);

    %Given the final coordinates, green boxes are drawn around each face.

    [newI,newI2]=draw_faces2(Results,Guess,Irgb,Correct_size,noface);

    %All the results are saved.

    save([filename(1:end-3),'mat']);

    imwrite(newI2,[filename(1:end-4),'_faces2.jpg']);
    imwrite(meatdif./max(max(meatdif)),[filename(1:end-4),'_meatdif.jpg']);
    imwrite((CLabsumMeat-CLabsum)./max(max(CLabsumMeat-CLabsum)),[filename(1:end-4),'_meatonly.jpg']);
    imwrite(newI,[filename(1:end-4),'_faces.jpg']);
    imwrite(CLabsum./max(max(CLabsum)),[filename(1:end-4),'_sum.jpg']);
    imwrite(CLabsumMeat./max(max(CLabsumMeat)),[filename(1:end-4),'_meat.jpg']);



