This tutorial will show you how
to use SVM-Light [1] for Object detection (face, car, person or any other
object recognition) in Matlab. Particularly,
it will implement a very basic Face Detector just to give you a bit of intuition
about how these things work. I have uploaded the source code of this tutorial here,
which is well commented and quite self explanatory. It shouldn’t
be hard to understand and modify it for any other object detection. All you have to do is to follow
the step in Section 2 to and
make it work on your system. Section 1
is the detailed explanation of the algorithm.
Section 1
Algorithm
Overview
There are two key factors involved
in object detection: (1) to choose an efficient feature descriptor, (2)
selection of proper classifier. I choose HOG [3] and off course SVM for this
tutorial. The approach is quite straightforward; to train a support vector
machine you need some positive (face) and some negative (non face) labeled examples.
For each training example, extract
features from each image and train a SVM to differentiate between the two
classes. For detection, scan the test image in sliding window fashion. For each
window extract features and run the classifier to determine whether or not
there is a face at that location.
Training:
There are 322 images originally and their
flipped version, so total of 644 positive (face) examples and the same way 2572 negative (non face) examples in the training dataset. To train the SVM you
will need to extract feature from both positive and negative examples and label
them as 1 for positive and -1 for negative examples in case of SVM-Light, and if
you want binary classification then labels should be 1 and 0 respectively. Below
is the example code.
if exist('model.mat','file')
load model;
else
[fpos, fneg] = features(pathPos,
pathNeg); % extract features
[ model ] = trainSVM( fpos,fneg ); % train SVM
save model model;
end
function [fpos, fneg] =
features(pathPos,pathNeg)
% extract features for positive examples
imlist = dir([pathPos '*.png']);
for i = 1:length(imlist)
im = imread([pathPos
imlist(i).name]);
fpos{i} =
HOG(double(im));
end
% extract features for negative examples
imlist = dir([pathNeg '*.png']);
for i = 1:length(imlist)
im = imread([pathNeg
imlist(i).name]);
fneg{i} =
HOG(double(im));
end
end
function [ model ] =
trainSVM( fpos,fneg )
SV = loadingV(fpos,fneg); % loading
and labeling each training example
fprintf('Training SVM..\n');
T = cell2mat(SV(2,:));
tP = SV(3,:)';
P = cell2mat(tP); % each row of P correspond to a training
example
model = svmlearn(P, T', '-t -g 0.3 -c 0.5');
fprintf('done. \n');
end
Testing:
Here is the example code for
detection.
function
detect(im,model,wSize)
%{
this function will take
three parameters
1.
im --> Test Image
2.
model --> trained model
3.
wStize --> Size of the window,
i.e. [24,32]
and draw rectangle on best
estimated window
%}
topLeftRow = 1;
topLeftCol = 1;
[bottomRightCol bottomRightRow d]
= size(im);
fcount = 1;
% this for loop scan the
entire image and extract features for each sliding window
for y =
topLeftCol:bottomRightCol-wSize(2)
for x = topLeftRow:bottomRightRow-wSize(1)
p1 = [x,y];
p2 = [x+(wSize(1)-1), y+(wSize(2)-1)];
po = [p1; p2];
img = imcut(po,im);
featureVector{fcount} =
HOG(double(img));
boxPoint{fcount} = [x,y];
fcount = fcount+1;
x = x+1;
end
end
lebel =
ones(length(featureVector),1);
P = cell2mat(featureVector);
% each row of P' correspond
to a window
[~, predictions] =
svmclassify(P',lebel,model); % classifying each window
[a, indx]= max(predictions);
bBox = cell2mat(boxPoint(indx));
rectangle('Position',[bBox(1),bBox(2),24,32],'LineWidth',1, 'EdgeColor','r');
end
Section 2
To compile this library in Matlab
you will need a C compiler and Mex function. So, let’s start with setting up
Mex.
1.
Setting
up Mex
If you have done this already,
skip this part. Setting up Mex is very easy; all you have to do is to
- Get and install a Matlab supported compiler.
- Type mex -setup in Matlab’s command window press enter and then to locate compiler enter ‘y’, to select Compiler enter its number. Similar as in the figure below.
Note: The list of
compilers shown on your system might be different from the list shown in this
example. The path names to your compilers might also be different. To read more about Mex click here and here
2.
Download and extract the source code of this tutorial from here, set it to
current working directory in matlab.
3.
Download
SVM-Light from here
4.
Extract
it into current working directory
5.
Add
following paths to main file, demo.m in our case.
addpath './svm_mex601/matlab';
addpath './svm_mex601/bin';
6.
The
library is precompiled; all binary files can be found in the ‘bin’ folder. Sometimes
they work just fine but sometimes they cause problems, maybe due to compatibility
and architectural issues. To compile them run compilemex()after adding the above paths. compilemex.m
is located in the directory ‘matlab’ and resulting binary files should
be stored in ‘bin’ directory. If compilemex fails then you would need to edit compilemex.m
as follows.
At
line number 4 replace ‘cd bin’
to ‘cd
svm_mex601/bin’ and add one more
‘cd
..’ after line 18
to point back to current working directory. As shown in the figure below
To
run the compilemex insert
break point after addpath lines as shown in the figure below, press F5 or click
on the run button and when debugger stops at the break point run compilemex() through command
window.
This
might show some warning but don’t worry everything will work fine, if it
is compiled successfully.
7.
Run
mex
HoG.cpp [2] through command
window to compile the HoG.cpp file.
That’s it, everything is now ready
to run this face detection code. To do so run the demo.m, this will read an
image and determine whether or not there is a
face in that image.
Results:
References
[3] N. Dalal, and B.
Triggs. Histograms of Oriented Gradients for Human
Detection. In Proc. CVPR, 2005.