📄 findface.m
字号:
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']);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -