Skip to content

Instantly share code, notes, and snippets.

@shanechin
Last active December 10, 2015 00:58
Show Gist options
  • Save shanechin/4354814 to your computer and use it in GitHub Desktop.
Save shanechin/4354814 to your computer and use it in GitHub Desktop.
function [ preds, acc, decvals ] = verifier( folds, images, output )
%VERIFIER Reads images and classifies based on gender
% Read certain facial features (eyes, nose, mouth, cheek)
% Train features using regression techniques in order to determine if
% male or female
vl_setup()
% Read the folds
q = read_lfw_folds(folds);
fin = fopen(folds);
nums = textscan(fin, '%d %d', 1, 'collectoutput', true);
num_men = nums{1}(1);
num_women = nums{1}(2);
total = num_men + num_women;
fclose(fin);
preds = [];
acc = [];
decvals = [];
%{ test on each male and female
tests = [34, 74, 2, 99, 131, 67, 122, 117, 11, 43];
trainlabels = [];
trainfeats = [];
testlabels = [];
testfeats = [];
% train on each fold except when i==j
for j=1:total
features = [];
% 20 pictures of each person
for k=1:20
% read images and train on features
a = strcat(images, '/', q.pairs{(j-1)*20+k});
im1 = single(rgb2gray(imread(a))) ./ 255;
% Each column of the 'frames' parameter indicates a point at which to extract a descriptor. The
% third row holds the 'scale' of the SIFT descriptor, which for reasons not relevant to our
% usage is one-twelfth of the side length of the SIFT window.
siftsize = 32;
% Here, we extract a SIFT descriptor at point (x, y), using a SIFT window that is 32 pixels on
% each side.
% left eye
x = 65;
y = 95;
frames = [x; y; siftsize/12; 0];
[f1, d1] = vl_sift(im1, 'frames', frames);
d1 = double(d1);
%{
right eye
x = 108;
y = 95;
frames = [x; y; siftsize/12; 0];
[f2, d2] = vl_sift(im1, 'frames', frames);
d2 = double(d2);
%}
% nose
x = 88;
y = 117;
frames = [x; y; siftsize/12; 0];
[f2, d2] = vl_sift(im1, 'frames', frames);
d2 = double(d2);
siftsize = 24;
%mouth
x = 88;
y = 149;
frames = [x; y; siftsize/12; 0];
[f3, d3] = vl_sift(im1, 'frames', frames);
d3 = double(d3);
siftsize = 28;
%left cheek
x = 57;
y = 128;
frames = [x; y; siftsize/12; 0];
[f4, d4] = vl_sift(im1, 'frames', frames);
d4 = double(d4);
%{
%right cheek
x = 120;
y = 128;
frames = [x; y; siftsize/12; 0];
[f6, d6] = vl_sift(im1, 'frames', frames);
d6 = double(d6);
%}
%{
siftsize = 50;
%forehead
x = 86;
y = 45;
frames = [x; y; siftsize/12; 0];
[f7, d7] = vl_sift(im1, 'frames', frames);
d7 = double(d7);
%}
feature = [d1; d2; d3; d4]';
features = [features; feature];
end
features = mean(features, 1);
if any(tests==j)
testfeats = [testfeats; features];
if j > num_men
testlabels = [testlabels; -1];
else
testlabels = [testlabels; 1];
end
else
trainfeats = [trainfeats; features];
labels = [];
if j > num_men
labels = -1;
else
labels = 1;
end
trainlabels = [trainlabels; labels];
end
end
% From libsvm, there are two functions you will need, which you should call as follows:
% train linearly. Why? because it's the only way it could have finished
% in a reasonable amount of time.
model = svmtrain(trainlabels, trainfeats, '-t 0');
[preds, acc, decvals] = svmpredict(testlabels, testfeats, model);
% where
% - trainlabels is column vector of training data labels (1 for "same", -1 for "different").
% - trainfeats is your normalized training data feature matrix, with one row per training
% sample.
% - options is a libsvm option string describing which kernel you want to use and various other
% options. Run svmtrain() without arguments to see a description of the options.
% - model is the trained SVM returned.
% - testlabels is a column vector with the labels of the test data. It's used only to calculate
% the accuracy of the SVM.
% - testfeats is the normalized test data feature matrix.
% - preds is a column vector holding the predicted class labels (1 or -1) for the test data.
% - acc is the accuracy of the predicted labels.
% - decvals is a column vector with the same size as preds, holding the signed distance from the
% decision boundary for each test sample. preds is just determined by the sign of decvals.
% print decision values, names, and actual decisions to output file
fTestOut = fopen(output, 'w');
fin = fopen(folds);
nums = textscan(fin, '%d %d', 1, 'collectoutput', true);
%num_men = nums{1}(1);
%num_women = nums{1}(2);
num_men = 7;
num_women = 3;
i = 1;
xp = sort(tests);
d = textscan(fin, '%s', nums{1}(1) + nums{1}(2), 'collectoutput', true);
for iperfold = 1:num_men
sub = d{1}{xp(i)};
fprintf(fTestOut, '%f\t', decvals(i));
fprintf(fTestOut, '%s\t', sub);
fprintf(fTestOut, '%d\n', 1);
i = i + 1;
end
for iperfold = 1:num_women
sub1 = d{1}{xp(i)};
fprintf(fTestOut, '%f\t', decvals(i));
fprintf(fTestOut, '%s\t', sub1);
fprintf(fTestOut, '%d\n', -1);
i = i + 1;
end
fclose(fTestOut);
fclose(fin);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment