Code covered by the BSD License  

Highlights from
Objects/Faces Detection Toolbox

image thumbnail
from Objects/Faces Detection Toolbox by Sebastien PARIS
Objects/Faces detection using Local Binary Patterns and Haar features

demo_haar.m
%% Demo illustrating HAAR features
%
%
% File : haar_featlist
%
% ---------------------------------------------
%
%   Haar features list parameters. Give all Haar features parameters
%   for a Image I (ny x nx) and dictionary of Haar pattern given
%   by rect_param
% 
%   Usage
%   ------
% 
%   F = haar_featlist([ny] , [nx] , [rect_param]);
% 
%   
%   Inputs
%   -------
% 
%   ny                                    Number of rows of the pattern (default ny = 24)
% 
%   nx                                    Number of columns of the pattern (default nx = ny)
% 
%   rect_param                            Features rectangles parameters (10 x nR), where nR is the total number of rectangles for the patterns.
%                                         (default Vertical(2 x 1) [1 ; -1] and Horizontal(1 x 2) [-1 , 1] patterns) 
% 										   rect_param(: , i) = [ip ; wp ; hp ; nrip ; nr ; xr ; yr ; wr ; hr ; sr], where
% 										   ip     index of the current pattern. ip = [1,...,nP], where nP is the total number of patterns
% 										   wp     width of the current pattern
% 										   hp     height of the current pattern
% 										   nrip   total number of rectangles for the current pattern ip
% 										   nr     index of the current rectangle of the current pattern, nr=[1,...,nrip]
% 										   xr,yr  top-left coordinates of the current rectangle of the current pattern
% 										   wr,hr  width and height of the current rectangle of the current pattern
% 										   sr     weights of the current rectangle of the current pattern 
% 
% 										   Please run gui_features_dictionary in the \gui subdir to build such parameters
% 
%  
%   Outputs
%   -------
%   
%   F                                     Features's list (6 x nF) in UINT32 where nF designs the total number of Haar features
%                                         F(: , i) = [if ; xf ; yf ; wf ; hf ; ir]
% 										  if     index of the current feature, if = [1,....,nF] where nF is the total number of Haar features  (see nbfeat_haar function)
% 										  xf,yf  top-left coordinates of the current feature of the current pattern
% 										  wf,hf  width and height of the current feature of the current pattern
% 										  ir     index of rectangle definition of the current feature in rect_param
%
%
%
%
% File : haar
%
% ---------------------------------------------
%
%   Compute HAAR features of image I
% 
%   Usage
% 
%   ------
% 
%   z                                     = haar(I , [options] );
% 
% 
%   Inputs
%   -------
% 
%   I                                     Images (Ny x Nx x N) in UINT8 format 
% 
%   options
% 
%          rect_param                     Features rectangles parameters (10 x nR), where nR is the total number of rectangles for the patterns.
%                                         (default Vertical(2 x 1) [1 ; -1] and Horizontal(1 x 2) [-1 , 1] patterns) 
% 										   rect_param(: , i) = [ip ; wp ; hp ; nrip ; nr ; xr ; yr ; wr ; hr ; sr], where
% 										   ip     index of the current pattern. ip = [1,...,nP], where nP is the total number of patterns
% 										   wp     width of the current pattern
% 										   hp     height of the current pattern
% 										   nrip   total number of rectangles for the current pattern ip
% 										   nr     index of the current rectangle of the current pattern, nr=[1,...,nrip]
% 										   xr,yr  top-left coordinates of the current rectangle of the current pattern
% 										   wr,hr  width and height of the current rectangle of the current pattern
% 										   sr     weights of the current rectangle of the current pattern 
% 
%          F                              Features's list (6 x nF) in UINT32 where nF designs the total number of Haar features
%                                         F(: , i) = [if ; xf ; yf ; wf ; hf ; ir]
% 										  if     index of the current feature, if = [1,....,nF] where nF is the total number of Haar features  (see nbfeat_haar function)
% 										  xf,yf  top-left coordinates of the current feature of the current pattern
% 										  wf,hf  width and height of the current feature of the current pattern
% 										  ir     index of rectangle definition of the current feature in rect_param
% 
%          standardize                    Standardize Input Images 1 = yes, 0 = no (default = 1)  
% 
% 		   usesingle                      Output in single format if usesingle = 1 (default usesingle = 0)
%
% 		   transpose                      Transpose Output if tranpose = 1 (in order to speed up Boosting algorithm, default tranpose = 0)
% 
% If compiled with the "OMP" compilation flag
% 
% 		  num_threads                    Number of threads. If num_threads = -1, num_threads = number of core  (default num_threads = -1)
% 
%    
% 
%   Outputs
%
%   -------
%   
%   z                                     Haar features matrix (nF x N) or (N x nF) (acoording to transpose option) in single/double format (according to usesingle options)
%                                         for each positions (y,x) in [1+h,...,ny-h]x[1+w,...,nx-w] and (w,h) integral block size.                              

%% First example : compute Haar features for nP type of patterns

clear, close all,clc,drawnow
load viola_24x24
options           = load('haar_dico_2.mat');

nP                = length(unique(options.rect_param(1 , :)));
Ny                = 24;
Nx                = 24;
N                 = 200;
options.F         = haar_featlist(Ny , Nx , options.rect_param);
pos               = find(y == 1);
neg               = find(y == -1);

I                 = (X(: , : , [pos(1:N) , neg(1:N)]));


tic,z             = haar(I , options);,toc

imagesc(z)
title(sprintf('Haar''s features with %d different patterns' , nP));
colormap(gray)

% disp('Press key to continue')
% pause

%% Second example : Display Haar features for a particular pattern scale 

clear, close all
load viola_24x24
options   = load('haar_dico_2.mat');

nF        = length(unique(options.rect_param(1 , :)));
[Ny,Nx,P] = size(X);
Nimage    = 100;
pattern   = [2 ; 1];


FF        = haar_featlist(Ny , Nx , options.rect_param);

ind       = find(sum(FF([4;5] , :) == repmat(pattern , 1 , size(FF , 2))) == 2);

options.F = FF(: , ind);
y         = options.F(3 , :);
x         = options.F(2 , :);
ind       = (y + 1 + (x)*Ny)';
% index     = repmat(ind , 1 , P) + repmat((0:Ny*Nx:Ny*Nx*(P-1))' , 1 , P);

z         = haar(X , options);

Ihaar     = zeros(Ny , Nx , P , class(z));

for i = 1:P
    
    Ihaar(ind + (i-1)*Ny*Nx) = z(: , i);
    Ihaar(: , : , i)         = Ihaar(: , : , i)';
    
end

figure
display_database(X);
title(sprintf('Original database'));

figure
display_database(Ihaar);
title(sprintf('Haar feature''s with pattern [%d %d]' , pattern(1) , pattern(2)));

% disp('Press key to continue')
% pause

%% Third example : Display a particular Haar feature computed on all the database 

clear, close all
load viola_24x24
options   = load('haar_dico_2.mat');

nP        = length(unique(options.rect_param(1 , :)));
Ny        = 24;
Nx        = 24;
nF        = 1;
FF        = haar_featlist(Ny , Nx , options.rect_param);
indpos    = find(y == 1);
indneg    = find(y == -1);

options.F = FF(: , nF);


tic,z     = haar(X , options);,toc

plot(indpos , z(indpos) , indneg , z(indneg) , 'r')
title(sprintf('Haar feature n=%d for %d different patterns' , nF , nP));
legend('Faces' , 'Non-faces')


% disp('Press key to continue')
% pause


%% Fourth example : Haar feature's computed on Face/Non-Face image

clear, close all
load viola_24x24
options   = load('haar_dico_2.mat');

Ny        = 24;
Nx        = 24;
options.F = haar_featlist(Ny , Nx , options.rect_param);
nF        = size(options.F , 2);

indpos    = find(y==1);
indneg    = find(y==-1);


tic,zpos  = haar(X(: , : , indpos(1)) , options );,toc
tic,zneg  = haar(X(: , : , indneg(1)) , options );,toc

figure
plot((1:nF)' , zpos , (1:nF)' , zneg , 'r')
title(sprintf('Haar feature''s computed on Face/Non-Face image'));

legend('Positive' , 'Negative')


% disp('Press key to continue')
% pause


%% Fifth example : Display Best Feature values computed on Viola-Jones database separating the 2 classes

load viola_24x24
load model_detector_haar_24x24
options   = load('haar_dico_2.mat');

bestFeat  = model.param(1 , 1); %40478+1;
thresh    = model.param(2 , 1);

[Ny,Nx,P] = size(X);


FF        = haar_featlist(Ny , Nx , options.rect_param);
options.F = FF(: , bestFeat);
z         = haar(X , options);


indpos    = find(y==1);
indneg    = find(y==-1);



figure
plot(indpos , z(indpos) , indneg , z(indneg) , 'r' , (1:length(z)) , thresh*ones(1,length(z)) , 'g')
legend('Faces' , 'Non-faces' , '\theta')
title(sprintf('Best Haar Feature = %d' , bestFeat))

figure
[Nneg , Xneg] = hist(double(z(indneg)) , 100 , 'r' );
bar(Xneg , Nneg)
set(get(gca , 'children') , 'facecolor' , [1 0 1])

hold on
[Npos , Xpos] = hist(double(z(indpos)) , 100 );
bar(Xpos , Npos);
plot(thresh*ones(1,2) , [0 , max([Nneg , Npos])] , 'g' , 'linewidth' , 2)
hold off
legend(get(gca , 'children') , '\theta', 'Faces' , 'Non-faces' )
title(sprintf('Best Haar Feature = %d' , bestFeat))

% disp('Press key to continue')
% pause



%% Sixth example : Display best Haar's Features from Adaboosting & FastAdaboosting


clear
load viola_24x24
options            = load('haar_dico_2.mat');

y                  = int8(y);

II                 = image_integral_standard(X);
[Ny , Nx , P]      = size(II);
Nimage             = 110;
nb_feats           = 3;
options.T          = nb_feats;

options.F          = haar_featlist(Ny , Nx , options.rect_param);
I                  = X(: , : , Nimage);


index              = randperm(length(y));

tic,options.param0 = haar_adaboost_binary_train_cascade(II(: , : , index) , y(index) , options);,toc  %a bit long ....%

options.G          = Haar_matG(Ny , Nx , options.rect_param);
tic,options.param1 = fast_haar_adaboost_binary_train_cascade(II(: , : , index) , y(index) , options);,toc



figure
imagesc(I)
hold on

best_feats          = (options.F(: , options.param0(1 , 1:nb_feats)));
x                   = double(best_feats(2 , :)) + 0.5 ;
y                   = double(best_feats(3 , :)) + 0.5;
w                   = best_feats(4 , :);
h                   = best_feats(5 , :);
indR                = fix(best_feats(6 , :) + 1)/10 + 1;
R                   = options.rect_param(4 , indR);

for f = 1 : nb_feats
    for r = 0:R(f)-1
        
        coeffw  = w(f)/options.rect_param(2 , indR(f) + r);
        coeffh  = h(f)/options.rect_param(3 , indR(f) + r);
        xr      = (x(f) + double(coeffw*options.rect_param(6 , indR(f) + r)));
        yr      = (y(f) + double(coeffh*options.rect_param(7 , indR(f) + r))) ;
        wr      = double(coeffw*(options.rect_param(8 , indR(f) + r)  - 0));
        hr      = double(coeffh*(options.rect_param(9 , indR(f) + r) - 0));
        s       = options.rect_param(10 , indR(f) + r);
        if (s == 1)
            
            color   = [0.9 0.9 0.9];
            
        else
            
            color   = [0.1 0.1 0.1];
            
        end
        hh      = rectangle('Position', [xr,  yr ,  wr ,  hr] );
        p       = patch([xr , xr+wr , xr + wr , xr] , [yr , yr , yr + hr , yr + hr] , color);
        alpha(p , 0.8);
        set(hh , 'linewidth' , 2 , 'EdgeColor' , [1 0 0])
        
    end
end
hold off
title(sprintf('Best %d Haar features with Adaboost' , nb_feats) , 'fontsize' , 13)
colormap(gray)



figure
imagesc(I)
hold on

best_feats          = (options.F(: , options.param1(1 , 1:nb_feats)));
x                   = double(best_feats(2 , :)) + 0.5 ;
y                   = double(best_feats(3 , :)) + 0.5;
w                   = best_feats(4 , :);
h                   = best_feats(5 , :);
indR                = fix(best_feats(6 , :) + 1)/10 + 1;
R                   = options.rect_param(4 , indR);

for f = 1 : nb_feats
    for r = 0:R(f)-1
        
        coeffw  = w(f)/options.rect_param(2 , indR(f) + r);
        coeffh  = h(f)/options.rect_param(3 , indR(f) + r);
        xr      = (x(f) + double(coeffw*options.rect_param(6 , indR(f) + r)));
        yr      = (y(f) + double(coeffh*options.rect_param(7 , indR(f) + r))) ;
        wr      = double(coeffw*(options.rect_param(8 , indR(f) + r)  - 0));
        hr      = double(coeffh*(options.rect_param(9 , indR(f) + r) - 0));
        s       = options.rect_param(10 , indR(f) + r);
        if (s == 1)
            
            color   = [0.9 0.9 0.9];
            
        else
            
            color   = [0.1 0.1 0.1];
            
        end
        hh      = rectangle('Position', [xr,  yr ,  wr ,  hr] );
        p       = patch([xr , xr+wr , xr + wr , xr] , [yr , yr , yr + hr , yr + hr] , color);
        alpha(p , 0.8);
        set(hh , 'linewidth' , 2 , 'EdgeColor' , [1 0 0])
        
    end
end
hold off

title(sprintf('Best %d Haar features with FastAdaboost' , nb_feats) , 'fontsize' , 13)
colormap(gray)


% disp('Press key to continue')
% pause


%% Seventh example : FastAdaboosting on Haar's features with 2 different types of pattern

clear
load viola_24x24
options                = load('haar_dico_2.mat');

[Ny , Nx , P]          = size(X);

options.T              = 100;
options.fine_threshold = 1;

II                     = image_integral_standard(X);
y                      = int8(y);

indp                   = find(y == 1);
indn                   = find(y ==-1);


options.F              = haar_featlist(Ny , Nx , options.rect_param);
options.G              = Haar_matG(Ny , Nx , options.rect_param);


tic,options.param      = fast_haar_adaboost_binary_train_cascade(II , y , options);,toc
[yest , fx]            = haar_adaboost_binary_predict_cascade(II ,  options);

tp                     = sum(yest(indp) == y(indp))/length(indp)
fp                     = 1 - sum(yest(indn) == y(indn))/length(indn)
perf                   = sum(yest == y)/length(y)

[tpp , fpp]            = basicroc(y , fx);


figure
plot(fx)


figure
plot(fpp , tpp , 'linewidth' , 2)
axis([-0.02 , 1.02 , -0.02 , 1.02])
grid on
title(sprintf('ROC for Fastadaboosting with T = %d' , options.T))


figure
plot(abs(options.param(3 , :)) , 'linewidth' , 2)
grid on
xlabel('Weaklearner m')
ylabel('|a_m|')
title('Weights of the Weaklearner')

% disp('Press key to continue')
% pause


Contact us at files@mathworks.com