open source pkg v1

This commit is contained in:
Vijay Yadev
2020-08-04 19:12:31 -04:00
parent bef213dba9
commit c389fc2c47
3708 changed files with 1624220 additions and 1 deletions

View File

@@ -0,0 +1,78 @@
function [ responses ] = CCNF_ncc_response( patches, patch_experts, normalisation_options, window_size, patch_length)
%PATCHRESPONSESVM Computing a patch response from a CCNF patch expert
% Using convolution, for testing purposes and not for actual speed
SigmaInv = patch_experts.SigmaInv;
patchSize = normalisation_options.patchSize;
if(~iscell(patches))
patches = {patches};
end
num_modalities = numel(patches);
responses = zeros(size(patches{1},1), patch_length);
% prepare the patches by normalising them to zscore (if used)
if(normalisation_options.zscore)
for i=1:num_modalities
patches{i} = zscore(patches{i});
end
end
for i = 1:size(patches{1},1)
norm_cross_corr = normalisation_options.useNormalisedCrossCorr == 1;
b = zeros(patch_length,1);
hl_per_modality = size(patch_experts.thetas,1);
for p=1:num_modalities
smallRegionVec = patches{p}(i,:);
smallRegion = reshape(smallRegionVec, window_size(1), window_size(2));
for hls = 1:hl_per_modality
% because the normalised cross correlation calculates the
% responses from a normalised template and a normalised image,
% normalise the thetas here and then apply the normalisation to
% the response
w = patch_experts.thetas(hls, 2:end, p);
norm_w = norm(w);
w = w/norm(w);
w = reshape(w, patchSize);
response = -norm_w * Cross_corr_resp(smallRegion, w, norm_cross_corr, patchSize) - patch_experts.thetas(hls,1,p);
% here we include the bias term as well, as it wasn't added
% during the response calculation
h1 = 1./(1 + exp(response(:)));
b = b + (2 * patch_experts.alphas((p-1)*hl_per_modality + hls) * h1);
end
end
response = SigmaInv \ b;
responses(i,:) = response(:);
end
responses = responses';
responses = responses(:);
end
function response = Cross_corr_resp(region, patchExpert, normalise_x_corr,patchSize)
if(normalise_x_corr)
[response] = normxcorr2(patchExpert, region);
response = response(patchSize(1):end-patchSize(1)+1,patchSize(2):end-patchSize(2)+1);
else
% this assumes that the patch is already normed, so just use
% cross-correlation
template = rot90(patchExpert,2);
response = conv2(region, template, 'valid');
end
end

View File

@@ -0,0 +1,77 @@
function [alphas, betas, thetas, similarities, sparsities] = Create_CCNF_Regressor(samples, labels, patch_length, similarity_types, sparsity_types, normalisation_options)
%CREATESVMCLASSIFIER creating a CCNF (LNF) patch expert given labeled
%training samples
% Add the CCNF library
addpath('../../CCNF/lib');
%% Preparing the similarity and sparsity function
% this will create a family of similarity neighbour node connections
similarities = {};
for i=1:size(similarity_types, 1)
type = similarity_types{i};
neighFn = @(x) similarity_neighbor_grid(x, sqrt(patch_length), type);
similarities = [similarities; {neighFn}];
end
sparsities = {};
% this will create a family of sparsity (inhibition) neighbour node
% connections
for i=1:size(sparsity_types, 1)
spFn = @(x) sparsity_grid(x, sqrt(patch_length), sparsity_types(i,1), sparsity_types(i,2));
sparsities = [sparsities; {spFn}];
end
%% Default training hyper-parameters
thresholdX = 1e-8;
thresholdFn = 1e-4;
max_iter = 200;
input_layer_size = size(samples, 1)-1;
% Some rule of thumb hyper-parameters if similarities are defined or not
if(numel(similarities) == 0)
best_lambda_a = 10000;
best_lambda_b = 0;
best_lambda_th = 0.1;
best_num_layer = 5;
else
best_lambda_a = 100;
best_lambda_b = 1000;
best_lambda_th = 0.1;
best_num_layer = 5;
end
% Checking if hyper-parameters are specified to be overriden
if(isfield(normalisation_options, 'lambda_a'))
best_lambda_a = normalisation_options.lambda_a;
end
if(isfield(normalisation_options, 'lambda_b'))
best_lambda_b = normalisation_options.lambda_b;
end
if(isfield(normalisation_options, 'lambda_th'))
best_lambda_th = normalisation_options.lambda_th;
end
if(isfield(normalisation_options, 'num_layers'))
best_num_layer = normalisation_options.num_layers;
end
% Initial parameter values
alphas = 1 * ones(best_num_layer,1);
betas = 1 * ones(numel(similarities) + numel(sparsities), 1);
initial_Theta = randInitializeWeights(input_layer_size, best_num_layer);
num_seqs = size(samples, 2)/patch_length;
labels = reshape(labels, patch_length, num_seqs);
% Actual training
[alphas, betas, thetas] = CCNF_training_bfgs(thresholdX, thresholdFn, samples, labels, alphas, betas, initial_Theta, best_lambda_a, best_lambda_b, best_lambda_th, similarities, sparsities, 'const', true, 'reinit', true, 'num_reinit', 20, 'num_seqs', num_seqs, 'lbfgs', 'max_iter', max_iter);
end

View File

@@ -0,0 +1,13 @@
function [ meanSquaredError, correlation, predictions ] = EvaluatePatchExpert( samples, labels, alphas, betas, thetas, similarities, sparsities, normalisationOptions, region_length )
%EVALUATEPATCHEXPERT Summary of this function goes here
% Detailed explanation goes here
num_seqs = size(samples, 2)/region_length;
% adding the bias term, and transposing to optimise
labels = reshape(labels, region_length, num_seqs);
[~,~,~, ~, correlation, meanSquaredError, predictions] = evaluate_CCNF_model(alphas, betas, thetas, samples, labels, similarities, sparsities, 0, 1, false);
end

View File

@@ -0,0 +1,132 @@
function [samples, labels, samples_unnormed, imgs_used] = ExtractTrainingSamples(examples, landmarkLoc, img_names, sigma, numSamples, landmark, normalisation_options)
%%
% for an area of interest of 19x19 and patch support region of 11x11, we
% would have 9x9=81 samples (9 is the single_input_size, 11 is
% patch_expert_support_size, 19x19 is normalisation_size, 9 would be the
% normalisation_side_size)
evaluation_size = normalisation_options.normalisationRegion;
patch_expert_support_size = normalisation_options.patchSize;
normalisation_side_size = (evaluation_size - 1)/2;
single_input_size = evaluation_size - patch_expert_support_size + 1;
% Determine the ratio of images to be sampled (most likely not all of them will be)
samples_per_img = (numSamples / (size(examples,1) * (1 + normalisation_options.rate_negative))) / (single_input_size(1)^2);
num_samples = int32(samples_per_img * (1 + normalisation_options.rate_negative) * size(examples,1) * (single_input_size(1)^2));
%% Initialise the samples and labels
samples = zeros(num_samples, patch_expert_support_size(1) * patch_expert_support_size(2));
labels = zeros(num_samples, 1);
%% Initialise the unnormed versions of the images
% This is done in order to assert our use of algorithms for calculating
% the responses, as for training we might use regular ml procedures,
% whereas for fitting normalised cross-correlation or just
% cross-correlation will be used, so keep some unnormed samples
samples_unnormed = zeros(int32(num_samples/300), evaluation_size(1)^2);
img_size = [size(examples,2), size(examples,3)];
% Extract only images of differing shaped faces to extract more diverse
% training samples
to_keep = FindDistantLandmarks(landmarkLoc, landmark, round(samples_per_img*size(examples,1)));
inds_all = 1:size(examples,1);
samples_to_use = inds_all(to_keep);
% Keep track of how many samples have been computed already
samples_filled = 1;
samples_unnormed_filled = 1;
%% parse the image names for reporting purposes
imgs_used = img_names(samples_to_use);
for i=1:numel(imgs_used)
[~,name,ext] = fileparts(imgs_used{i});
imgs_used{i} = [name, ext];
end
for i=samples_to_use
% Do rate_negative negatives and a single positive
for p=1:normalisation_options.rate_negative+1
% create a gaussian
corrPoint = landmarkLoc(i,landmark,:);
% Ignore occluded points
if(corrPoint(1) == 0)
break;
end
startX = 1 - corrPoint(1);
startY = 1 - corrPoint(2);
patchWidth = img_size(2);
patchHeight = img_size(1);
[X, Y] = meshgrid(startX:patchWidth + startX-1, startY:patchHeight + startY-1);
response = exp(-0.5*(X.^2+Y.^2)/(sigma^2));
% Choose positive or negative sample
if(p==normalisation_options.rate_negative+1)
sample_centre = squeeze(corrPoint) + round(1*randn(2,1));
else
sample_centre = squeeze(corrPoint) + round(10*randn(2,1));
end
sample_centre = round(sample_centre);
sample_centre(sample_centre <= normalisation_side_size(1)) = normalisation_side_size(1) + 1;
sample_centre(sample_centre > img_size(1)-normalisation_side_size(1)) = img_size(1) - normalisation_side_size(1) - 1;
patches = squeeze(examples(i, sample_centre(2) - normalisation_side_size:sample_centre(2) + normalisation_side_size, sample_centre(1) - normalisation_side_size:sample_centre(1) + normalisation_side_size));
side = (single_input_size - 1)/2;
responses = response(sample_centre(2) - side(2):sample_centre(2) + side(2), sample_centre(1) - side(1):sample_centre(1) + side(1));
if(samples_unnormed_filled <= size(samples_unnormed,1))
% even if correct size is not initialised Matlab will
% sort that out (would only happen once anyway)
samples_unnormed(samples_unnormed_filled,:) = patches(:);
samples_unnormed_filled = samples_unnormed_filled + 1;
end
% if we want to normalise each patch individualy do it here
patch = im2col(patches, patch_expert_support_size, 'sliding')';
response = im2col(responses, [1,1], 'sliding');
labels(samples_filled:samples_filled+size(patch,1)-1,:) = response;
samples(samples_filled:samples_filled+size(patch,1)-1,:) = patch;
samples_filled = samples_filled + size(patch,1);
end
end
if(normalisation_options.useNormalisedCrossCorr == 1)
mean_curr = mean(samples, 2);
patch_normed = samples - repmat(mean_curr,1, patch_expert_support_size(1)*patch_expert_support_size(2));
% Normalising the patches using the L2 norm
scaling = sqrt(sum(patch_normed.^2,2));
scaling(scaling == 0) = 1;
patch_normed = patch_normed ./ repmat(scaling, 1, patch_expert_support_size(1)*patch_expert_support_size(2));
samples = patch_normed;
clear 'patch_normed';
end
% Only keep the filled samples
samples = samples(1:samples_filled-1,:);
labels = labels(1:samples_filled-1,:);
if((samples_filled-1)/(single_input_size(1)*single_input_size(2)) < size(samples_unnormed,1))
samples_unnormed = samples_unnormed(1:(samples_filled-1)/(single_input_size(1)*single_input_size(2)),:);
end
end

View File

@@ -0,0 +1,41 @@
function [to_keep] = FindDistantLandmarks(landmarkLoc, landmark_num, num_to_keep)
% First align all of them
a = landmarkLoc(:,:,1);
b = landmarkLoc(:,:,2);
offset_x = mean(a,2);
offset_y = mean(b,2);
landmark_loc_off = cat(3, bsxfun(@plus, a, -offset_x), bsxfun(@plus, b, -offset_y));
fixed_x = landmark_loc_off(:,:,1);
fixed_y = landmark_loc_off(:,:,2);
% Extract the relevant landmarks
fixed_x_l = fixed_x(:,landmark_num);
fixed_y_l = fixed_y(:,landmark_num);
obs = cat(2, fixed_x_l, fixed_y_l);
% Discard landmarks that are very close to each other, so that we only
% keep more diverse images
D = squareform(pdist(obs));
to_keep = true(size(landmarkLoc,1),1);
for i = 1:(size(landmarkLoc,1) - num_to_keep)
diversity_score = mean(D,2);
a = min(diversity_score);
lowest = find(diversity_score == a);
lowest = lowest(1);
to_keep(lowest) = 0;
D(:,~to_keep) = 0;
D(~to_keep,:) = 200;
end
end

View File

@@ -0,0 +1,120 @@
function [ normalisation_options ] = Parse_settings( sigma, ratio_neg, num_samples, varargin)
%PARSE_SETTINGS Summary of this function goes here
% Detailed explanation goes here
% creating the parameters to use when training colour (intensity) patches
normalisation_options = struct;
% this is what currently is expected (although could potentially have
% bigger or smaller patches, this should not be bigger that the patch
% available in examples and negExamples
normalisation_options.patchSize = [11 11];
% The region size of a region that is taken for training around an
% aligned or misaligned landmark
if(sum(strcmp(varargin,'normalisation_size')))
ind = find(strcmp(varargin,'normalisation_size')) + 1;
normalisation_options.normalisationRegion = [varargin{ind}, varargin{ind}];
else
normalisation_options.normalisationRegion = [21 21];
end
% This specifies the split of data ratios
normalisation_options.ccnf_ratio = 0.9; % proportion of data used for cross-validating CCNFs
% the rest is used for testing and provides the F1 and accuracy scores
if(any(strcmp(varargin, 'patch_types')))
ind = find(strcmp(varargin,'patch_types')) + 1;
normalisation_options.patch_type = varargin{ind};
else
normalisation_options.patch_type = {'reg'};
end
if(any(strcmp(varargin, 'sparsity_types')))
ind = find(strcmp(varargin,'sparsity_types')) + 1;
if(~isempty( varargin{ind}))
normalisation_options.sparsity = 1;
normalisation_options.sparsity_types = varargin{ind};
else
normalisation_options.sparsity = 0;
normalisation_options.sparsity_types = [];
end
else
normalisation_options.sparsity = 0;
normalisation_options.sparsity_types = [];
end
if(any(strcmp(varargin, 'lambda_a')))
ind = find(strcmp(varargin,'lambda_a')) + 1;
normalisation_options.lambda_a = varargin{ind};
end
if(any(strcmp(varargin, 'lambda_b')))
ind = find(strcmp(varargin,'lambda_b')) + 1;
normalisation_options.lambda_b = varargin{ind};
end
if(any(strcmp(varargin, 'lambda_th')))
ind = find(strcmp(varargin,'lambda_th')) + 1;
normalisation_options.lambda_th = varargin{ind};
end
if(any(strcmp(varargin, 'num_layers')))
ind = find(strcmp(varargin,'num_layers')) + 1;
normalisation_options.num_layers = varargin{ind};
end
if(any(strcmp(varargin, 'num_bins')))
ind = find(strcmp(varargin,'num_bins')) + 1;
normalisation_options.num_hog_bins = varargin{ind};
else
normalisation_options.num_hog_bins = 9;
end
normalisation_options.numSamples = num_samples;
normalisation_options.useZeroMeanPerPatch = 1;
normalisation_options.useNormalisedCrossCorr = 1;
normalisation_options.zscore = 0;
% Should invalid pixels be taken into account when normalising (yes in
% case of depth and no in case of colour)
normalisation_options.ignoreInvalidInMeanStd = 0; % we don't care about invalid pixels at this time (black is valid here) TODO background simulation?
normalisation_options.setIllegalToPost = 0;
if(sum(strcmp(varargin,'use_bu')))
ind = find(strcmp(varargin,'use_bu')) + 1;
normalisation_options.bu = varargin{ind};
else
normalisation_options.bu = 1;
end
if(sum(strcmp(varargin,'use_mpie')))
ind = find(strcmp(varargin,'use_mpie')) + 1;
normalisation_options.mpie = varargin{ind};
else
normalisation_options.mpie = 1;
end
if(sum(strcmp(varargin,'use_wild')))
ind = find(strcmp(varargin,'use_wild')) + 1;
normalisation_options.wild = varargin{ind};
else
normalisation_options.wild = 0;
end
normalisation_options.sigma = sigma;
normalisation_options.rate_negative = ratio_neg;
% the similarities need to be tested separately (1,2,3 and 4) and
% together all, vs hor/ver and diags, and none of course
if(any(strcmp(varargin, 'similarity_types')))
ind = find(strcmp(varargin,'similarity_types')) + 1;
normalisation_options.similarity_types = varargin{ind};
else
normalisation_options.similarity_types = [];
end
end

View File

@@ -0,0 +1,38 @@
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
sigma = 1;
num_samples = 5e5;
scales = [0.25,0.35,0.5];
frontalView = 1;
profileViewInds = [];
version = 'cofw';
ratio_neg = 5;
norm = 1;
data_loc = 'cofw_';
rng(0);
similarities = {};
sparsity = 1;
sparsity_types = [];
lambda_a = 100;
lambda_b = 1000;
lambda_th = 1;
num_layers = 7;
for s=scales
Train_all_patch_experts(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19, 'similarity_types', similarities, 'sparsity', sparsity,...
'sparsity_types', sparsity_types, 'lambda_a', lambda_a, 'lambda_b', lambda_b, 'lambda_th', lambda_th, 'num_layers', num_layers);
end

View File

@@ -0,0 +1,38 @@
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
sigma = 1;
num_samples = 2.5e6;
scales = [0.25,0.35,0.5,1.0];
frontalView = 1;
profileViewInds = [2,3,4];
version = 'general';
ratio_neg = 10;
norm = 1;
data_loc = 'combined_';
rng(0);
similarities = {[1,2]; [3, 4]};
sparsity = 1;
sparsity_types = [4,6];
lambda_a = 200;
lambda_b = 7500;
lambda_th = 1;
num_layers = 7;
for s=scales
Train_all_patch_experts(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19, 'similarity_types', similarities, 'sparsity', sparsity,...
'sparsity_types', sparsity_types, 'lambda_a', lambda_a, 'lambda_b', lambda_b, 'lambda_th', lambda_th, 'num_layers', num_layers);
end

View File

@@ -0,0 +1,38 @@
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
sigma = 1;
num_samples = 5e5;
scales = [0.25,0.35,0.5];
frontalView = 1;
profileViewInds = [2,3,4];
version = 'multi_pie';
ratio_neg = 5;
norm = 1;
data_loc = 'mpie_';
rng(0);
similarities = {[1,2]; [3, 4]};
sparsity = 1;
sparsity_types = [4,6];
lambda_a = 100;
lambda_b = 1000;
lambda_th = 1;
num_layers = 7;
for s=scales
Train_all_patch_experts(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19, 'similarity_types', similarities, 'sparsity', sparsity,...
'sparsity_types', sparsity_types, 'lambda_a', lambda_a, 'lambda_b', lambda_b, 'lambda_th', lambda_th, 'num_layers', num_layers);
end

View File

@@ -0,0 +1,38 @@
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
sigma = 1;
num_samples = 2e6;
scales = [0.25,0.35,0.5,1.0];
frontalView = 1;
profileViewInds = [2];
version = 'wild';
ratio_neg = 5;
norm = 1;
data_loc = 'wild_';
rng(0);
similarities = {[1,2]; [3, 4]};
sparsity = 1;
sparsity_types = [4,6];
lambda_a = 200;
lambda_b = 7500;
lambda_th = 1;
num_layers = 7;
for s=scales
Train_all_patch_experts(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19, 'similarity_types', similarities, 'sparsity', sparsity,...
'sparsity_types', sparsity_types, 'lambda_a', lambda_a, 'lambda_b', lambda_b, 'lambda_th', lambda_th, 'num_layers', num_layers);
end

View File

@@ -0,0 +1,152 @@
function [correlations, rmsErrors, patchExperts, visiIndex, centres, imgs_used, normalisation_options] = Train_CCNF_patches(training_loc, view, scale, sigma, ratio_neg, num_samples, varargin)
%% creating the model
% creating the regression models
normalisation_options = Parse_settings( sigma, ratio_neg, num_samples, varargin{:});
if(sum(strcmp(varargin,'data_loc')))
ind = find(strcmp(varargin,'data_loc')) + 1;
data_loc = varargin{ind};
data_loc = sprintf(['%s\\' data_loc '%s_%s.mat'], training_loc, num2str(scale), num2str(view));
else
data_loc = sprintf('%s\\wild_%s_%s.mat', training_loc, num2str(scale), num2str(view));
end
load(data_loc);
examples = all_images;
landmark_loc = landmark_locations;
clear 'all_images'
numPoints = size(landmark_loc,2);
correlations = zeros(1, numPoints);
rmsErrors = zeros(1, numPoints);
patchExperts = cell(1, numPoints);
for j=1:numPoints
pause(0);
% can only do mirroring if there is no yaw
if((numPoints == 68 || numPoints == 29 )&& centres(2) == 0)
% Do not redo a mirror feature (just flip them)
if(numPoints == 68)
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
else
mirrorInds = [1,2; 3,4; 5,7; 6,8; 9,10; 11,12; 13,15; 14,16; 17,18; 19,20; 23,24];
end
mirror_idx = j;
if(any(mirrorInds(:,1)==j))
mirror_idx = mirrorInds(mirrorInds(:,1)==j,2);
elseif(any(mirrorInds(:,2)==j))
mirror_idx = mirrorInds(mirrorInds(:,2)==j,1);
end
if(mirror_idx~=j & correlations(1,mirror_idx) ~= 0)
correlations(1,j) = correlations(1,mirror_idx);
rmsErrors(1, j) = rmsErrors(1,mirror_idx);
patchExperts{1, j} = patchExperts{1,mirror_idx};
num_hl = size(patchExperts{1,mirror_idx}.thetas, 1);
num_mod = size(patchExperts{1,mirror_idx}.thetas, 3);
for m=1:num_mod
for hl=1:num_hl
w = reshape(patchExperts{1,mirror_idx}.thetas(hl, 2:end, m),11,11);
w = fliplr(w);
w = reshape(w, 121,1);
patchExperts{1, j}.thetas(hl, 2:end, m) = w;
end
end
fprintf('Feature %d done\n', j);
continue;
end
end
imgs_used = {};
if(visiIndex(j))
tic;
% instead of loading the patches compute them here:
num_samples = normalisation_options.numSamples;
[samples, labels, unnormed_samples, imgs_used_n] = ExtractTrainingSamples(examples, landmark_loc, actual_imgs_used, sigma, num_samples, j, normalisation_options);
imgs_used = union(imgs_used, imgs_used_n);
% add the bias term
samples = [ones(1,size(samples,1)); samples'];
region_length = normalisation_options.normalisationRegion - normalisation_options.patchSize + 1;
region_length = region_length(1) * region_length(2);
num_examples = size(samples, 2);
% this part sets the split boundaries for training and test subsets
train_ccnf_start = 1;
train_ccnf_end = int32(normalisation_options.ccnf_ratio * num_examples - 1);
% make sure we don't split a full training region apart
train_ccnf_end = train_ccnf_end - mod(train_ccnf_end, region_length);
test_start = train_ccnf_end + 1;
test_end = size(samples,2);
samples_train = samples(:,train_ccnf_start:train_ccnf_end);
labels_train = labels(train_ccnf_start:train_ccnf_end);
samples_test = samples(:,test_start:test_end);
labels_test = labels(test_start:test_end);
% Set up the patch expert
similarity_types = normalisation_options.similarity_types;
patch_expert.similarity_types = similarity_types;
patch_expert.sparsity = normalisation_options.sparsity;
patch_expert.sparsity_types = normalisation_options.sparsity_types;
patch_expert.patch_expert_type = 'CCNF';
% The actual regressor training
[alpha, betas, thetas, similarities, sparsities] = Create_CCNF_Regressor(samples_train, labels_train, region_length, similarity_types, normalisation_options.sparsity_types, normalisation_options);
% The learned patch expert
patch_expert.alphas = alpha;
patch_expert.betas = betas;
patch_expert.thetas = thetas;
% if we have a SigmaInv, we don't need betas anymore (or
% similarity and sparsity functions for that matter), compute
% in a single sample for efficiency
[ ~, ~, Precalc_Bs_flat, ~ ] = CalculateSimilarities( 1, zeros(size(samples,1),region_length), similarities, sparsities, labels_train(1:region_length), true);
Precalc_B_flat = Precalc_Bs_flat{1};
SigmaInv = CalcSigmaCCNFflat(patch_expert.alphas, patch_expert.betas, region_length, Precalc_B_flat, eye(region_length), zeros(region_length));
patch_expert.SigmaInv = SigmaInv;
% Evaluate the patch expert
[rmsError, corr,~] = EvaluatePatchExpert(samples_test, labels_test, alpha, betas, thetas, similarities, sparsities, normalisation_options, region_length);
fprintf('Rms error %.3f, correlation %.3f\n', rmsError, corr);
% Assert that our normalisation and different fitting are equivalent
% normed_samples = samples(:,1:size(unnormed_samples,1)*region_length);
% [~, ~, responses_ccnf] = EvaluatePatchExpert(normed_samples, labels(1:size(unnormed_samples,1)*region_length), alpha, betas, thetas, similarities, sparsities, normalisation_options, region_length);
% [responses_ccnf_ncc] = CCNF_ncc_response(unnormed_samples, patch_expert, normalisation_options, normalisation_options.normalisationRegion, region_length);
% assert(norm(responses_ccnf-responses_ccnf_ncc)< 10e-1);
correlations(1,j) = corr;
rmsErrors(1, j) = rmsError;
patchExperts{1, j} = patch_expert(:);
fprintf('Landmark %d done\n', j);
clear samples
clear samples_test
clear samples_train
clear labels
clear unnormed_samples
clear imgs_used_n
toc;
end
end
end

View File

@@ -0,0 +1,155 @@
function Train_all_patch_experts(trainingLoc, frontalView, profile_views, scaling, sigma, version, varargin)
% need some documentation here
if(sum(strcmp(varargin,'ratio_neg')))
ind = find(strcmp(varargin,'ratio_neg')) + 1;
ratio_neg = varargin{ind};
else
ratio_neg = 20;
end
if(sum(strcmp(varargin,'num_samples')))
ind = find(strcmp(varargin,'num_samples')) + 1;
num_samples = varargin{ind};
else
num_samples = 5e5;
end
patch_experts = struct;
patch_experts.types = {'reg'};
patch_experts.correlations = [];
patch_experts.rms_errors = [];
patch_experts.patch_experts = cell(numel(patch_experts.types), 1);
% first do the frontal view
[visiIndex, centres, patch_experts, imgs_used, norm_options] = ...
AppendTraining(trainingLoc, frontalView, scaling, sigma, [], [], patch_experts, ratio_neg, num_samples, varargin{:});
fprintf('Frontal done\n');
% now do the profile views
for i=1:numel(profile_views)
[visiIndex, centres, patch_experts, imgs_used_profile] = ...
AppendTraining(trainingLoc, profile_views(i), scaling, sigma, visiIndex, centres, patch_experts, ratio_neg, num_samples, varargin{:});
fprintf('Profile %d done\n', i);
imgs_used = cat(1, imgs_used, imgs_used_profile);
end
% saving time by not retraining mirrored (left/right) views, but just
% filpping the patch expert
for i=1:numel(profile_views)
[visiIndex, centres, patch_experts] = ...
AppendMirror(visiIndex, centres, patch_experts, numel(profile_views) - i + 2, varargin{:});
fprintf('Profile %d done\n', i + numel(profile_views));
end
% output the training
locationTxtCol = sprintf('trained/ccnf_patches_%s_%s.txt', num2str(scaling), version);
locationMlabCol = sprintf('trained/ccnf_patches_%s_%s.mat', num2str(scaling), version);
Write_patch_experts_ccnf(locationTxtCol, locationMlabCol, scaling, centres, visiIndex, patch_experts, norm_options, [7,9,11,15]);
% save the images used
location_imgs_used = sprintf('trained/imgs_used_%s.mat', version);
save(location_imgs_used, 'imgs_used');
end
function [visi_index, centres, patches_m, imgs_used, norm_options] = AppendTraining(training_data_loc, view, scale, sigma, visibilities_init, centres_init, patches_m_init, ratio_neg, num_samples, varargin)
patches_m = patches_m_init;
[correlations, rms_errors, patch_experts, visi_index, centres, imgs_used, norm_options] = Train_CCNF_patches(training_data_loc, view, scale, sigma, ratio_neg, num_samples, varargin{:});
if(numel(patches_m_init.correlations) > 0)
patches_m.correlations = cat(1, patches_m_init.correlations, correlations);
patches_m.rms_errors = cat(1, patches_m_init.rms_errors, rms_errors);
patches_m.patch_experts = cat(1, patches_m_init.patch_experts, patch_experts);
else
patches_m.correlations = correlations;
patches_m.rms_errors = rms_errors;
patches_m.patch_experts = patch_experts;
end
% also add the visibility indices and centres, as that will need to be
% output to the patch expert when it's written out
if(numel(visibilities_init) > 0)
visi_index = cat(1, visibilities_init, visi_index);
centres = cat(1, centres_init, centres);
end
end
function [visiIndex, centres, patches_m] = AppendMirror(visiIndexInit, centresInit, patches_m, index, varargin)
if(numel(visiIndexInit) > 0)
corr_T = patches_m.correlations(index,:);
if(numel(corr_T) == 66)
% this specifies the mirrored points, say 1 in left profile becomes 17
% in right profile if mirrored, non-mirrored points don't need to be
% specified, they just get flipped but index remains the same
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,63;66,64];
elseif(numel(corr_T) == 68)
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
end
corr_T = swap(corr_T, mirrorInds(:,1), mirrorInds(:,2));
patches_m.correlations = cat(1, patches_m.correlations, corr_T);
AccT = patches_m.rms_errors(index,:);
AccT = swap(AccT, mirrorInds(:,1), mirrorInds(:,2));
patches_m.rms_errors = cat(1, patches_m.rms_errors, AccT);
visiIndexT = visiIndexInit(index,:);
visiIndexT = swap(visiIndexT, mirrorInds(:,1), mirrorInds(:,2));
visiIndex = cat(1, visiIndexInit, visiIndexT);
% mirroring of the orientation involves flipping yaw or roll (we
% assume only views with one rotation will be present (say only
% pitch or yaw or roll)
centresMirror = [centresInit(index,1), -centresInit(index,2), -centresInit(index,3)];
centres = cat(1, centresInit, centresMirror);
patchExpertMirror = patches_m.patch_experts(index,:);
patchExpertMirrorT1 = patchExpertMirror(1,mirrorInds(:,1),:);
patchExpertMirrorT2 = patchExpertMirror(1,mirrorInds(:,2),:);
patchExpertMirror(1,mirrorInds(:,2),:) = patchExpertMirrorT1;
patchExpertMirror(1,mirrorInds(:,1),:) = patchExpertMirrorT2;
% To flip a patch expert it
for p=1:size(patchExpertMirror,2)
if(visiIndexT(p))
num_hl = size(patchExpertMirror{p}.thetas, 1);
num_mod = size(patchExpertMirror{p}.thetas, 3);
for m=1:num_mod
for hl=1:num_hl
w = reshape(patchExpertMirror{p}.thetas(hl, 2:end, m),11,11);
w = fliplr(w);
w = reshape(w, 121,1);
patchExpertMirror{p}.thetas(hl, 2:end, m) = w;
end
end
end
end
patches_m.patch_experts = cat(1, patches_m.patch_experts, patchExpertMirror);
end
end
function arr = swap(arr, ind1, ind2)
val1 = arr(ind1);
val2 = arr(ind2);
arr(ind1) = val2;
arr(ind2) = val1;
end

View File

@@ -0,0 +1,139 @@
function Write_patch_experts_ccnf(location_txt, location_mlab, trainingScale, centers, visiIndex, patch_experts, normalisationOptions, w_sizes)
save(location_mlab, 'patch_experts', 'trainingScale', 'centers', 'visiIndex', 'normalisationOptions');
patches_file = fopen(location_txt, 'w');
[n_views, n_landmarks, ~] = size(patch_experts.correlations);
% fprintf(patches_file, '# scaling factor of training\r\n%f\r\n', trainingScale);
fwrite(patches_file, trainingScale, 'float64');
% write out the scaling factor as this is what will be used when
% fitting on the window
% fprintf(patches_file, '# number of views\r\n%d\r\n', n_views);
fwrite(patches_file, n_views, 'int');
% Write out the information about the view's and centers here
% fprintf(patches_file, '# centers of the views\r\n');
for i=1:n_views
% this indicates that we're writing a 3x1 double matrix
writeMatrixBin(patches_file, centers(i,:)', 6);
end
% fprintf(patches_file, '# visibility indices per view\r\n');
for i=1:n_views
% this indicates that we're writing a 3x1 double matrix
writeMatrixBin(patches_file, visiIndex(i,:)', 4);
end
% fprintf(patches_file, '# Sigma component matrices being used in these patches\r\n');
% fprintf(patches_file, '# Number of windows sizes\r\n');
% fprintf(patches_file, '%d\r\n', numel(w_sizes));
fwrite(patches_file, numel(w_sizes), 'int');
for w = 1:numel(w_sizes)
% fprintf(patches_file, '# Size of window\r\n');
% fprintf(patches_file, '%d\r\n', w_sizes(w));
fwrite(patches_file, w_sizes(w), 'int');
similarities = {};
response_side_length = w_sizes(w);
for st=1:size(patch_experts.patch_experts{1,1}.similarity_types, 1)
type_sim = patch_experts.patch_experts{1,1}.similarity_types{st};
neighFn = @(x) similarity_neighbor_grid(x, response_side_length, type_sim);
similarities = cat(1, similarities, {neighFn});
end
sparsities = {};
for st=1:size(patch_experts.patch_experts{1,1}.sparsity_types, 1)
spFn = @(x) sparsity_grid(x, response_side_length, patch_experts.patch_experts{1,1}.sparsity_types(st,1), patch_experts.patch_experts{1,1}.sparsity_types(st,2));
sparsities = cat(1, sparsities, {spFn});
end
region_length = response_side_length^2;
% Adding the sparsities here if needed (assuming we are using an
% 11x11 support area, hard-coded)
[ ~, PrecalcQ2s, ~, ~ ] = CalculateSimilarities( 1, zeros(122,region_length), similarities, sparsities, zeros(region_length,1), true);
PrecalcQ2s = PrecalcQ2s{1};
% fprintf(patches_file, '# Number of Sigma components\r\n');
fwrite(patches_file, numel(PrecalcQ2s), 'int');
for q2=1:numel(PrecalcQ2s)
writeMatrixBin(patches_file, PrecalcQ2s{q2}, 5);
end
end
% fprintf(patches_file, '# Patches themselves (1 line patches of a vertex)\r\n');
for i=1:n_views
for j=1:n_landmarks
% Write out that we're writing a ccnf patch expert of 11x11 support region
fwrite(patches_file, 5, 'int');
fwrite(patches_file, 11, 'int');
fwrite(patches_file, 11, 'int');
if(~visiIndex(i,j))
% Write out that there won't be any neurons for this
% landmark
fwrite(patches_file, 0, 'int');
fwrite(patches_file, 0, 'int');
else
num_neurons = size(patch_experts.patch_experts{i,j}.thetas, 1);
% CCNF patch(5), width, height, num_neurons, Patch(2), neuron_type,
% normalisation, bias, alpha, rows, cols, type
num_modalities = size(patch_experts.patch_experts{i,j}.thetas, 3);
fwrite(patches_file, num_neurons, 'int');
for n=1:num_neurons
for m=1:num_modalities
if(strcmp(patch_experts.types{m}, 'reg'))
type = 0;
elseif(strcmp(patch_experts.types{m}, 'grad'))
type = 1;
else
fprintf('Not supported patch type\n');
type = 0;
end
% normalise the w
w = patch_experts.patch_experts{i,j}.thetas(n, 2:end, m);
norm_w = norm(w);
w = w/norm(w);
bias = patch_experts.patch_experts{i,j}.thetas(n, 1, m);
alpha = patch_experts.patch_experts{i,j}.alphas((m-1)*num_neurons+n);
% also add patch confidence based on correlation scores
fwrite(patches_file, 2, 'int');
fwrite(patches_file, type, 'int');
fwrite(patches_file, norm_w, 'float64');
fwrite(patches_file, bias, 'float64');
fwrite(patches_file, alpha, 'float64');
% the actual weight matrix
writeMatrixBin(patches_file, reshape(w, 11, 11), 5);
end
end
% Write out the betas
for b=1:numel(patch_experts.patch_experts{i,j}.betas)
fwrite(patches_file, patch_experts.patch_experts{i,j}.betas(b), 'float64');
end
% finally write out the confidence
fwrite(patches_file, patch_experts.correlations(i,j), 'float64');
end
end
end
fclose(patches_file);

View File

@@ -0,0 +1,13 @@
clear;
load('trained/ccnf_patches_1_general.mat');
% now drop the first 17 points
visiIndex = visiIndex(:,18:end);
patch_experts.correlations = patch_experts.correlations(:,18:end);
patch_experts.rms_errors = patch_experts.rms_errors(:,18:end);
patch_experts.patch_experts = patch_experts.patch_experts(:,18:end);
Write_patch_experts_ccnf('trained/ccnf_patches_1.00_inner.txt',...
'trained/ccnf_patches_1.00_inner.mat', trainingScale, centers,...
visiIndex, patch_experts, normalisationOptions, [7,9,11,15]);

View File

@@ -0,0 +1,56 @@
function [ display_array ] = generateDisplayData( X )
%GENERATEDISPLAYDATA Summary of this function goes here
% Detailed explanation goes here
example_width = 11;
example_height = 11;
% Compute rows, cols
[m n] = size(X);
% Compute number of items to display
display_rows = floor(sqrt(m));
display_cols = ceil(m / display_rows);
% Between images padding
pad = 1;
% Setup blank display
display_array = double(zeros(pad + display_rows * (example_height + pad), ...
pad + display_cols * (example_width + pad)));
% Copy each example into a patch on the display array
curr_ex = 1;
for j = 1:display_rows
for i = 1:display_cols
if curr_ex > m,
break;
end
% Copy the patch
% if(isa(X, 'uint8'))
display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...
pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...
reshape(X(curr_ex, :), example_height, example_width);
% else
% % Get the max value of the patch
% minVal = min(X(curr_ex, X(curr_ex,:)~=0)) - 10;
% if(numel(minVal) < 1)
% minVal = 0;
% end
% maxVal = double(max(X(curr_ex,:)-minVal))/255.0;
% if(numel(minVal) < 1 || maxVal == 0)
% maxVal = 1;
% end
% display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...
% pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...
% reshape((X(curr_ex, :)-minVal)/maxVal, example_height, example_width);
% end
curr_ex = curr_ex + 1;
end
if curr_ex > m,
break;
end
end
end

View File

@@ -0,0 +1,13 @@
Scripts for training continuous conditional neural field (CCNF, or alternatively Local Neural Field - LNF) patch experts.
This requires data preparation first (not included with the source code), to prepare the data go to '../data_preparation/readme.txt'.
To train the patch experts run:
Script_Training_wild.m (using in-the-wild data)
Script_Training_multi_pie (using multi-pie data)
Script_Training_general (using combined data)
To prepare the inner face general patch expert run:
extract_inner.m
The trained patch experts are included in the './trained/' folder, the experts you train might differ slightly based on the version of Matlab used.

View File

@@ -0,0 +1,16 @@
% for easier readibility write them row by row
function writeMatrix(fileID, M, type)
fprintf(fileID, '%d\r\n', size(M,1));
fprintf(fileID, '%d\r\n', size(M,2));
fprintf(fileID, '%d\r\n', type);
for i=1:size(M,1)
if(type == 4 || type == 0)
fprintf(fileID, '%d ', M(i,:));
else
fprintf(fileID, '%.9f ', M(i,:));
end
fprintf(fileID, '\r\n');
end
end

View File

@@ -0,0 +1,37 @@
% for easier readibility write them row by row
function writeMatrixBin(fileID, M, type)
% 4 bytes each for the description
fwrite(fileID, size(M,1), 'uint');
fwrite(fileID, size(M,2), 'uint');
fwrite(fileID, type, 'uint');
% Convert the matrix to OpenCV format (row minor as opposed to column
% minor)
M = M';
% type 0 - uint8, 1 - int8, 2 - uint16, 3 - int16, 4 - int, 5 -
% float32, 6 - float64
% Write out the matrix itself
switch type
case 0
type = 'uint8';
case 1
type = 'int8';
case 2
type = 'uint16';
case 3
type = 'int16';
case 4
type = 'int';
case 5
type = 'float32';
case 6
type = 'float64';
otherwise
type = 'float32';
end
fwrite(fileID, M, type);
end

View File

@@ -0,0 +1,35 @@
function Collect_all_patches(trainingLoc, frontalView, profile_views, scaling, sigma, version, varargin)
% need some documentation here
if(sum(strcmp(varargin,'ratio_neg')))
ind = find(strcmp(varargin,'ratio_neg')) + 1;
ratio_neg = varargin{ind};
else
ratio_neg = 20;
end
if(sum(strcmp(varargin,'num_samples')))
ind = find(strcmp(varargin,'num_samples')) + 1;
num_samples = varargin{ind};
else
num_samples = 5e5;
end
% first do the frontal view
AppendTraining(trainingLoc, frontalView, scaling, sigma, ratio_neg, num_samples, 0, version, varargin{:});
fprintf('Frontal done\n');
% now do the profile views
for i=1:numel(profile_views)
AppendTraining(trainingLoc, profile_views(i), scaling, sigma, ratio_neg, num_samples, i, version, varargin{:});
fprintf('Profile %d done\n', i);
end
end
function AppendTraining(training_data_loc, view, scale, sigma, ratio_neg, num_samples, varargin)
Collect_patches_view(training_data_loc, view, scale, sigma, ratio_neg, num_samples, varargin{:});
end

View File

@@ -0,0 +1,71 @@
function Collect_patches_view(training_loc, view, scale, sigma, ratio_neg, num_samples, profile_id, version, varargin)
%% creating the model
% creating the regression models
normalisation_options = Parse_settings( sigma, ratio_neg, num_samples, varargin{:});
if(sum(strcmp(varargin,'data_loc')))
ind = find(strcmp(varargin,'data_loc')) + 1;
data_loc = varargin{ind};
data_loc = sprintf(['%s\\' data_loc '%s_%s.mat'], training_loc, num2str(scale), num2str(view));
else
data_loc = sprintf('%s\\wild_%s_%s.mat', training_loc, num2str(scale), num2str(view));
end
load(data_loc);
examples = all_images;
landmark_loc = landmark_locations;
clear 'all_images'
numPoints = size(landmark_loc,2);
done = false(numPoints,1);
for j=1:numPoints
% can only do mirroring if there is no yaw
if((numPoints == 68 || numPoints == 29 )&& centres(2) == 0)
% Do not redo a mirror feature (just flip them)
if(numPoints == 68)
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
else
mirrorInds = [1,2; 3,4; 5,7; 6,8; 9,10; 11,12; 13,15; 14,16; 17,18; 19,20; 23,24];
end
mirror_idx = j;
if(any(mirrorInds(:,1)==j))
mirror_idx = mirrorInds(mirrorInds(:,1)==j,2);
elseif(any(mirrorInds(:,2)==j))
mirror_idx = mirrorInds(mirrorInds(:,2)==j,1);
end
if(mirror_idx~=j & done(mirror_idx))
continue;
end
end
imgs_used = {};
if(visiIndex(j))
tic;
% instead of loading the patches compute them here:
num_samples = normalisation_options.numSamples;
[samples, labels, imgs_used_n] = ExtractTrainingSamples(examples, landmark_loc, actual_imgs_used, sigma, num_samples, j, normalisation_options);
imgs_used = union(imgs_used, imgs_used_n);
% add the bias term
samples = [ones(1,size(samples,1)); samples'];
if(centres(2) == 0)
save(sprintf('E:/menpo_data/%s_data%.2f_frontal_%d.mat', version, scale, j), 'samples', 'labels', '-v7.3');
else
save(sprintf('E:/menpo_data/%s_data%.2f_profile%d_%d.mat', version, scale, profile_id, j), 'samples', 'labels', '-v7.3');
end
fprintf('Landmark %d done\n', j);
clear samples
clear labels
done(j) = true;
end
end
end

View File

@@ -0,0 +1,133 @@
function [samples, labels, imgs_used] = ExtractTrainingSamples(examples, landmarkLoc, img_names, sigma, numSamples, landmark, normalisation_options)
%%
% for an area of interest of 19x19 and patch support region of 11x11, we
% would have 9x9=81 samples (9 is the single_input_size, 11 is
% patch_expert_support_size, 19x19 is normalisation_size, 9 would be the
% normalisation_side_size)
evaluation_size = normalisation_options.normalisationRegion;
patch_expert_support_size = normalisation_options.patchSize;
normalisation_side_size = (evaluation_size - 1)/2;
single_input_size = evaluation_size - patch_expert_support_size + 1;
% Determine the ratio of images to be sampled (most likely not all of them will be)
samples_per_img = (numSamples / (size(examples,1) * (1 + normalisation_options.rate_negative))) / (single_input_size(1)^2);
num_samples = int32(samples_per_img * (1 + normalisation_options.rate_negative) * size(examples,1) * (single_input_size(1)^2));
%% Initialise the samples and labels
samples = zeros(num_samples, patch_expert_support_size(1) * patch_expert_support_size(2));
labels = zeros(num_samples, 1);
%% Initialise the unnormed versions of the images
% This is done in order to assert our use of algorithms for calculating
% the responses, as for training we might use regular ml procedures,
% whereas for fitting normalised cross-correlation or just
% cross-correlation will be used, so keep some unnormed samples
% samples_unnormed = zeros(int32(num_samples/300), evaluation_size(1)^2);
img_size = [size(examples,2), size(examples,3)];
% Extract only images of differing shaped faces to extract more diverse
% training samples
to_keep = FindDistantLandmarks(landmarkLoc, landmark, round(samples_per_img*size(examples,1)));
inds_all = 1:size(examples,1);
samples_to_use = inds_all(to_keep);
% Keep track of how many samples have been computed already
samples_filled = 1;
samples_unnormed_filled = 1;
%% parse the image names for reporting purposes
imgs_used = img_names(samples_to_use);
for i=1:numel(imgs_used)
[~,name,ext] = fileparts(imgs_used{i});
imgs_used{i} = [name, ext];
end
for i=samples_to_use
% Do rate_negative negatives and a single positive
for p=1:normalisation_options.rate_negative+1
% create a gaussian
corrPoint = landmarkLoc(i,landmark,:);
% Ignore occluded points
if(corrPoint(1) == 0)
break;
end
startX = 1 - corrPoint(1);
startY = 1 - corrPoint(2);
patchWidth = img_size(2);
patchHeight = img_size(1);
[X, Y] = meshgrid(startX:patchWidth + startX-1, startY:patchHeight + startY-1);
response = exp(-0.5*(X.^2+Y.^2)/(sigma^2));
% Choose positive or negative sample
if(p==normalisation_options.rate_negative+1)
sample_centre = squeeze(corrPoint) + round(1*randn(2,1));
else
sample_centre = squeeze(corrPoint) + round(10*randn(2,1));
end
sample_centre = round(sample_centre);
sample_centre(sample_centre <= normalisation_side_size(1)) = normalisation_side_size(1) + 1;
sample_centre(sample_centre > img_size(1)-normalisation_side_size(1)) = img_size(1) - normalisation_side_size(1) - 1;
patches = squeeze(examples(i, sample_centre(2) - normalisation_side_size:sample_centre(2) + normalisation_side_size, sample_centre(1) - normalisation_side_size:sample_centre(1) + normalisation_side_size));
side = (single_input_size - 1)/2;
responses = response(sample_centre(2) - side(2):sample_centre(2) + side(2), sample_centre(1) - side(1):sample_centre(1) + side(1));
% if(samples_unnormed_filled <= size(samples_unnormed,1))
% % even if correct size is not initialised Matlab will
% % sort that out (would only happen once anyway)
% samples_unnormed(samples_unnormed_filled,:) = patches(:);
% samples_unnormed_filled = samples_unnormed_filled + 1;
% end
% if we want to normalise each patch individualy do it here
patch = im2col(patches, patch_expert_support_size, 'sliding')';
response = im2col(responses, [1,1], 'sliding');
labels(samples_filled:samples_filled+size(patch,1)-1,:) = response;
samples(samples_filled:samples_filled+size(patch,1)-1,:) = patch;
samples_filled = samples_filled + size(patch,1);
end
end
% Only keep the filled samples
samples = samples(1:samples_filled-1,:);
labels = labels(1:samples_filled-1,:);
if(normalisation_options.useNormalisedCrossCorr == 1)
mean_curr = mean(samples, 2);
patch_normed = samples - repmat(mean_curr,1, patch_expert_support_size(1)*patch_expert_support_size(2));
% Normalising the patches using the L2 norm
scaling = sqrt(sum(patch_normed.^2,2));
scaling(scaling == 0) = 1;
patch_normed = patch_normed ./ repmat(scaling, 1, patch_expert_support_size(1)*patch_expert_support_size(2));
samples = patch_normed;
clear 'patch_normed';
end
% if((samples_filled-1)/(single_input_size(1)*single_input_size(2)) < size(samples_unnormed,1))
% samples_unnormed = samples_unnormed(1:(samples_filled-1)/(single_input_size(1)*single_input_size(2)),:);
% end
end

View File

@@ -0,0 +1,41 @@
function [to_keep] = FindDistantLandmarks(landmarkLoc, landmark_num, num_to_keep)
% First align all of them
a = landmarkLoc(:,:,1);
b = landmarkLoc(:,:,2);
offset_x = mean(a,2);
offset_y = mean(b,2);
landmark_loc_off = cat(3, bsxfun(@plus, a, -offset_x), bsxfun(@plus, b, -offset_y));
fixed_x = landmark_loc_off(:,:,1);
fixed_y = landmark_loc_off(:,:,2);
% Extract the relevant landmarks
fixed_x_l = fixed_x(:,landmark_num);
fixed_y_l = fixed_y(:,landmark_num);
obs = cat(2, fixed_x_l, fixed_y_l);
% Discard landmarks that are very close to each other, so that we only
% keep more diverse images
D = squareform(pdist(obs));
to_keep = true(size(landmarkLoc,1),1);
for i = 1:(size(landmarkLoc,1) - num_to_keep)
diversity_score = mean(D,2);
a = min(diversity_score);
lowest = find(diversity_score == a);
lowest = lowest(1);
to_keep(lowest) = 0;
D(:,~to_keep) = 0;
D(~to_keep,:) = 200;
end
end

View File

@@ -0,0 +1,120 @@
function [ normalisation_options ] = Parse_settings( sigma, ratio_neg, num_samples, varargin)
%PARSE_SETTINGS Summary of this function goes here
% Detailed explanation goes here
% creating the parameters to use when training colour (intensity) patches
normalisation_options = struct;
% this is what currently is expected (although could potentially have
% bigger or smaller patches, this should not be bigger that the patch
% available in examples and negExamples
normalisation_options.patchSize = [11 11];
% The region size of a region that is taken for training around an
% aligned or misaligned landmark
if(sum(strcmp(varargin,'normalisation_size')))
ind = find(strcmp(varargin,'normalisation_size')) + 1;
normalisation_options.normalisationRegion = [varargin{ind}, varargin{ind}];
else
normalisation_options.normalisationRegion = [21 21];
end
% This specifies the split of data ratios
normalisation_options.ccnf_ratio = 0.9; % proportion of data used for cross-validating CCNFs
% the rest is used for testing and provides the F1 and accuracy scores
if(any(strcmp(varargin, 'patch_types')))
ind = find(strcmp(varargin,'patch_types')) + 1;
normalisation_options.patch_type = varargin{ind};
else
normalisation_options.patch_type = {'reg'};
end
if(any(strcmp(varargin, 'sparsity_types')))
ind = find(strcmp(varargin,'sparsity_types')) + 1;
if(~isempty( varargin{ind}))
normalisation_options.sparsity = 1;
normalisation_options.sparsity_types = varargin{ind};
else
normalisation_options.sparsity = 0;
normalisation_options.sparsity_types = [];
end
else
normalisation_options.sparsity = 0;
normalisation_options.sparsity_types = [];
end
if(any(strcmp(varargin, 'lambda_a')))
ind = find(strcmp(varargin,'lambda_a')) + 1;
normalisation_options.lambda_a = varargin{ind};
end
if(any(strcmp(varargin, 'lambda_b')))
ind = find(strcmp(varargin,'lambda_b')) + 1;
normalisation_options.lambda_b = varargin{ind};
end
if(any(strcmp(varargin, 'lambda_th')))
ind = find(strcmp(varargin,'lambda_th')) + 1;
normalisation_options.lambda_th = varargin{ind};
end
if(any(strcmp(varargin, 'num_layers')))
ind = find(strcmp(varargin,'num_layers')) + 1;
normalisation_options.num_layers = varargin{ind};
end
if(any(strcmp(varargin, 'num_bins')))
ind = find(strcmp(varargin,'num_bins')) + 1;
normalisation_options.num_hog_bins = varargin{ind};
else
normalisation_options.num_hog_bins = 9;
end
normalisation_options.numSamples = num_samples;
normalisation_options.useZeroMeanPerPatch = 1;
normalisation_options.useNormalisedCrossCorr = 1;
normalisation_options.zscore = 0;
% Should invalid pixels be taken into account when normalising (yes in
% case of depth and no in case of colour)
normalisation_options.ignoreInvalidInMeanStd = 0; % we don't care about invalid pixels at this time (black is valid here) TODO background simulation?
normalisation_options.setIllegalToPost = 0;
if(sum(strcmp(varargin,'use_bu')))
ind = find(strcmp(varargin,'use_bu')) + 1;
normalisation_options.bu = varargin{ind};
else
normalisation_options.bu = 1;
end
if(sum(strcmp(varargin,'use_mpie')))
ind = find(strcmp(varargin,'use_mpie')) + 1;
normalisation_options.mpie = varargin{ind};
else
normalisation_options.mpie = 1;
end
if(sum(strcmp(varargin,'use_wild')))
ind = find(strcmp(varargin,'use_wild')) + 1;
normalisation_options.wild = varargin{ind};
else
normalisation_options.wild = 0;
end
normalisation_options.sigma = sigma;
normalisation_options.rate_negative = ratio_neg;
% the similarities need to be tested separately (1,2,3 and 4) and
% together all, vs hor/ver and diags, and none of course
if(any(strcmp(varargin, 'similarity_types')))
ind = find(strcmp(varargin,'similarity_types')) + 1;
normalisation_options.similarity_types = varargin{ind};
else
normalisation_options.similarity_types = [];
end
end

View File

@@ -0,0 +1,40 @@
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
sigma = 1;
num_samples = 4.5e6; % Making sure all data is used
scales = [0.25,0.35,0.5,1.0];
frontalView = 1;
profileViewInds = [2,3,4];
version = 'menpo_train';
ratio_neg = 10;
norm = 1;
data_loc = 'menpo_train_';
rng(0);
for s=scales
Collect_all_patches(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19);
end
version = 'menpo_valid';
data_loc = 'menpo_valid_';
rng(0);
for s=scales
Collect_all_patches(root, frontalView, profileViewInds,...
s, sigma, version, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', data_loc,...
'normalisation_size', 19);
end

View File

@@ -0,0 +1 @@
Data collection for train CE-CLM on Menpo data.

View File

@@ -0,0 +1,11 @@
The code here prepares the training images and labels into a format that can be easilly used to train SVR and CCNF regressors.
Just run "scripts/Prepare_data_wild_all.m" for data needed to train patch experts for in-the-wild experiments.(you have to have the relevant datasets, but they are all available online at http://ibug.doc.ic.ac.uk/resources/facial-point-annotations/)
Run "scripts/Prepare_data_Multi_PIE_all.m" (you have to have the multi-pie dataset and labels)
Run "scripts/Prepare_data_general_all.m" (you have to have both of the datasets, and you have to run "scripts/Prepare_data_wild_all.m" and scripts/Prepare_data_Multi_PIE_all.m" first.
Run "scripts/Prepare_data_menpo_all.m" (you have to have the Menpo challenge training data - https://ibug.doc.ic.ac.uk/resources/2nd-facial-landmark-tracking-competition-menpo-ben/)
PDM model used is trained on 2D landmark labels using Non-Rigid-Structure for motion (code can be found http://www.cl.cam.ac.uk/~tb346/res/ccnf/pdm_generation.zip)

View File

@@ -0,0 +1,9 @@
function [RotFull] = AddOrthRow(RotSmall)
% We can work out these values from the small version of the rotation matrix Rx * Ry * Rz (if you plug in values you can work it out, just slightly tedious)
RotFull = zeros(3,3);
RotFull(1:2, :) = RotSmall;
RotFull(3,1) = RotSmall(1, 2) * RotSmall(2, 3) - RotSmall(1, 3) * RotSmall(2, 2);
RotFull(3,2) = RotSmall(1, 3) * RotSmall(2, 1) - RotSmall(1, 1) * RotSmall(2, 3);
RotFull(3,3) = RotSmall(1, 1) * RotSmall(2, 2) - RotSmall(1, 2) * RotSmall(2, 1);

View File

@@ -0,0 +1,22 @@
function [ R, T ] = AlignShapesKabsch ( alignFrom, alignTo )
%ALIGN3DSHAPES Summary of this function goes here
% Detailed explanation goes here
dims = size(alignFrom, 2);
alignFromMean = alignFrom - repmat(mean(alignFrom), size(alignFrom,1),1);
alignToMean = alignTo - repmat(mean(alignTo), size(alignTo,1),1);
[U, ~, V] = svd( alignFromMean' * alignToMean);
% make sure no reflection is there
d = sign(det(V*U'));
corr = eye(dims);
corr(end,end) = d;
R = V*corr*U';
T = mean(alignTo) - (R * mean(alignFrom)')';
T = T';
end

View File

@@ -0,0 +1,30 @@
function [ A, T, error, alignedShape ] = AlignShapesWithScale( alignFrom, alignTo )
%ALIGNSHAPESWITHSCALE Summary of this function goes here
% Detailed explanation goes here
numPoints = size(alignFrom,1);
meanFrom = mean(alignFrom);
meanTo = mean(alignTo);
alignFromMeanNormed = bsxfun(@minus, alignFrom, meanFrom);
alignToMeanNormed = bsxfun(@minus, alignTo, meanTo);
% scale now
sFrom = sqrt(sum(alignFromMeanNormed(:).^2)/numPoints);
sTo = sqrt(sum(alignToMeanNormed(:).^2)/numPoints);
s = sTo / sFrom;
alignFromMeanNormed = alignFromMeanNormed/sFrom;
alignToMeanNormed = alignToMeanNormed/sTo;
[R, t] = AlignShapesKabsch(alignFromMeanNormed, alignToMeanNormed);
A = s * R;
aligned = (A * alignFrom')';
T = mean(alignTo - aligned);
alignedShape = bsxfun(@plus, aligned, T);
error = mean(sum((alignedShape - alignTo).^2,2));
end

View File

@@ -0,0 +1,11 @@
function [Rot] = AxisAngle2Rot(axisAngle)
theta = norm(axisAngle, 2);
nx = axisAngle / theta;
nx = [ 0 -nx(3) nx(2);
nx(3) 0 -nx(1);
-nx(2) nx(1) 0 ];
Rot = eye(3) + sin(theta) * nx + (1-cos(theta))*nx^2;

View File

@@ -0,0 +1,11 @@
function [Rot] = Euler2Rot(euler)
rx = euler(1);
ry = euler(2);
rz = euler(3);
Rx = [1 0 0; 0 cos(rx) -sin(rx); 0 sin(rx) cos(rx)];
Ry = [cos(ry) 0 sin(ry); 0 1 0; -sin(ry) 0 cos(ry)];
Rz = [cos(rz) -sin(rz) 0; sin(rz) cos(rz) 0; 0 0 1];
Rot = Rx * Ry * Rz;

View File

@@ -0,0 +1,7 @@
function [shape3D] = GetShape3D(M, V, p)
shape3D = M + V * p;
shape3D = reshape(shape3D, numel(shape3D) / 3, 3);
end

View File

@@ -0,0 +1,20 @@
function [shape2D] = GetShapeOrtho(M, V, p, global_params)
% M - mean shape vector
% V - eigenvectors
% p - parameters of non-rigid shape
% V_exp
% p_exp
% global_params includes scale, euler rotation, translation,
% R - rotation matrix
% T - translation vector (tx, ty)
R = Euler2Rot(global_params(2:4));
T = [global_params(5:6); 0];
a = global_params(1);
shape3D = GetShape3D(M, V, p);
shape2D = bsxfun(@plus, a * R*shape3D', T);
shape2D = shape2D';
end

View File

@@ -0,0 +1,103 @@
function [normX, normY, meanShape, Transform] = ProcrustesAnalysis(x, y, options)
% Translate all elements to origin and scale to 1
normX = zeros(size(x));
normY = zeros(size(y));
for i = 1:size(x,1)
offsetX = mean(x(i,:));
offsetY = mean(y(i,:));
Transform.offsetX(i) = offsetX;
Transform.offsetY(i) = offsetY;
normX(i,:) = x(i,:) - offsetX;
normY(i,:) = y(i,:) - offsetY;
% Get the Frobenius norm, to scale the shapes to unit size
scale = norm([normX(i,:) normY(i,:)], 'fro');
Transform.scale(i) = scale;
normX(i,:) = normX(i,:)/scale;
normY(i,:) = normY(i,:)/scale;
end
% Rotate elements untill all of them have the same orientation
% the initial estimate of rotation would be the first element
% if change is less than 1% stop (shouldn't take more than 2 steps)
change = 0.1;
meanShape = [ normX(1,:); normY(1,:) ]';
Transform.Rotation = zeros(size(x,1),1);
for i = 1:30
% align all of the shapes to the mean shape
% remember all orientations to get the mean one
orientations = zeros(size(normX,1),1);
for j = 1:size(x,1)
% do SVD of mean * X'
currentShape = [ normX(j,:); normY(j,:) ]';
[U, ~, V] = svd( meanShape' * currentShape);
rot = V*U';
if(asin(rot(2,1)) > 0)
orientations(j) = real(acos(rot(1,1)));
else
orientations(j) = real(-acos(rot(1,1)));
end
Transform.Rotation(j) = Transform.Rotation(j) + orientations(j);
currentShape = currentShape * rot;
normX(j,:) = currentShape(:,1)';
normY(j,:) = currentShape(:,2)';
end
% recalculate the mean shape;
oldMean = meanShape;
meanShape = [mean(normX); mean(normY)]';
% rotate the mean shape to mean rotation
meanOrientation = mean(orientations);
% Do this only the first time
if(i==1)
rotM = [ cos(-meanOrientation) -sin(-meanOrientation); sin(-meanOrientation) cos(-meanOrientation) ];
meanShape = meanShape * rotM;
end
% scale mean shape to unit
meanScale = norm(meanShape, 'fro');
meanShape = meanShape*(1/meanScale);
% find frobenious norm
diff = norm(oldMean - meanShape, 'fro');
if(diff/norm(oldMean,'fro') < change)
break;
end
end
% transform to tangent space to preserve linearities
% get the scaling factors for each shape
if(options.TangentSpaceTransform)
scaling = [ normX normY ] * [ meanShape(:,1)' meanShape(:,2)']';
for i=1:size(x,1)
normX(i,:) = normX(i,:) * (1 / scaling(i));
normY(i,:) = normY(i,:) * (1 / scaling(i));
end
end

View File

@@ -0,0 +1,139 @@
function [ normX, normY, normZ, meanShape, Transform ] = ProcrustesAnalysis3D( x, y, z, tangentSpace, meanShape )
%PROCRUSTESANALYSIS3D Summary of this function goes here
% Detailed explanation goes here
meanProvided = false;
if(nargin > 4)
meanProvided = true;
end
% Translate all elements to origin
normX = zeros(size(x));
normY = zeros(size(y));
normZ = zeros(size(z));
for i = 1:size(x,1)
offsetX = mean(x(i,:));
offsetY = mean(y(i,:));
offsetZ = mean(z(i,:));
Transform.offsetX(i) = offsetX;
Transform.offsetY(i) = offsetY;
Transform.offsetZ(i) = offsetZ;
normX(i,:) = x(i,:) - offsetX;
normY(i,:) = y(i,:) - offsetY;
normZ(i,:) = z(i,:) - offsetZ;
end
% Rotate elements untill all of them have the same orientation
% the initial estimate of rotation would be the first element
% if change is less than 1% stop (shouldn't take more than 2 steps)
change = 0.1;
if(~meanProvided)
meanShape = [ mean(normX); mean(normY); mean(normZ) ]';
end
% scale all the shapes to mean shape
% Get the Frobenius norm, to scale the shapes to mean size (still want to
% retain mm)
meanScale = norm(meanShape, 'fro');
for i = 1:size(x,1)
scale = norm([normX(i,:) normY(i,:) normZ(i,:)], 'fro')/meanScale;
normX(i,:) = normX(i,:)/scale;
normY(i,:) = normY(i,:)/scale;
normZ(i,:) = normZ(i,:)/scale;
end
Transform.RotationX = zeros(size(x,1),1);
Transform.RotationY = zeros(size(x,1),1);
Transform.RotationZ = zeros(size(x,1),1);
for i = 1:30
% align all of the shapes to the mean shape
% remember all orientations to get the mean one (in euler angle form, pitch, yaw roll)
orientationsX = zeros(size(normX,1),1);
orientationsY = zeros(size(normX,1),1);
orientationsZ = zeros(size(normX,1),1);
for j = 1:size(x,1)
currentShape = [normX(j,:); normY(j,:); normZ(j,:)]';
% we want to align the current shape to the mean one
[ R, T ] = AlignShapesKabsch(currentShape, meanShape);
eulers = Rot2Euler(R);
orientationsX(j) = eulers(1);
orientationsY(j) = eulers(2);
orientationsZ(j) = eulers(3);
Transform.RotationX(j) = eulers(1);
Transform.RotationY(j) = eulers(2);
Transform.RotationZ(j) = eulers(3);
currentShape = R * currentShape';
normX(j,:) = currentShape(1,:);
normY(j,:) = currentShape(2,:);
normZ(j,:) = currentShape(3,:);
end
% recalculate the mean shape
% if(~meanProvided)
oldMean = meanShape;
meanShape = [mean(normX); mean(normY); mean(normZ)]';
meanScale = norm(meanShape, 'fro');
% end
for j = 1:size(x,1)
scale = norm([normX(j,:) normY(j,:) normZ(j,:)], 'fro')/meanScale;
normX(j,:) = normX(j,:)/scale;
normY(j,:) = normY(j,:)/scale;
normZ(j,:) = normZ(j,:)/scale;
end
if(i==1 && ~meanProvided)
% rotate the mean shape to mean rotation
meanOrientationX = mean(orientationsX);
meanOrientationY = mean(orientationsY);
meanOrientationZ = mean(orientationsZ);
R = Euler2Rot([meanOrientationX, meanOrientationY, meanOrientationZ]);
meanShape = (R * meanShape')';
end
% find frobenious norm
diff = norm(oldMean - meanShape, 'fro');
if(diff/norm(oldMean,'fro') < change)
break;
end
end
% transform to tangent space to preserve linearities
% get the scaling factors for each shape
if(tangentSpace)
[ normX, normY, normZ] = TangentSpaceTransform(normX, normY, normZ, meanShape);
end
end

View File

@@ -0,0 +1,11 @@
function [ axisAngle ] = Rot2AxisAngle( Rot )
%ROT2AXISANGLE Summary of this function goes here
% Detailed explanation goes here
theta = acos((trace(Rot) - 1) / 2);
vec = 1.0/(2*sin(theta));
vec = vec * [Rot(3,2) - Rot(2,3), Rot(1,3) - Rot(3,1), Rot(2,1) - Rot(1,2)];
axisAngle = vec * theta;
end

View File

@@ -0,0 +1,12 @@
function [euler] = Rot2Euler(R)
q0 = sqrt( 1 + R(1,1) + R(2,2) + R(3,3) ) / 2;
q1 = (R(3,2) - R(2,3)) / (4*q0) ;
q2 = (R(1,3) - R(3,1)) / (4*q0) ;
q3 = (R(2,1) - R(1,2)) / (4*q0) ;
yaw = asin(2*(q0*q2 + q1*q3));
pitch= atan2(2*(q0*q1-q2*q3), q0*q0-q1*q1-q2*q2+q3*q3);
roll = atan2(2*(q0*q3-q1*q2), q0*q0+q1*q1-q2*q2-q3*q3);
euler = [pitch, yaw, roll];

View File

@@ -0,0 +1,17 @@
function [ transformedX, transformedY, transformedZ ] = TangentSpaceTransform( x, y, z, meanShape )
%TANGENTSPACETRANSFORM Summary of this function goes here
% Detailed explanation goes here
scaling = [ x y z] * [ meanShape(:,1)' meanShape(:,2)' meanShape(:,3)']';
for i=1:size(x,1)
x(i,:) = x(i,:) * (1 / scaling(i));
y(i,:) = y(i,:) * (1 / scaling(i));
z(i,:) = z(i,:) * (1 / scaling(i));
end
transformedX = x * mean(scaling);
transformedY = y * mean(scaling);
transformedZ = z * mean(scaling);
end

View File

@@ -0,0 +1,345 @@
function [ a, R, T, T3D, params, error, shapeOrtho ] = fit_PDM_ortho_proj_to_2D( M, E, V, shape2D, f, cx, cy)
%FITPDMTO2DSHAPE Summary of this function goes here
% Detailed explanation goes here
params = zeros(size(E));
hidden = false;
% if some of the points are unavailable modify M, V, and shape2D (can
% later infer the actual shape from this)
if(sum(shape2D(:)==0) > 0)
hidden = true;
% which indices to remove
inds_to_rem = shape2D(:,1) == 0 | shape2D(:,2) == 0;
shape2D = shape2D(~inds_to_rem,:);
inds_to_rem = repmat(inds_to_rem, 3, 1);
M_old = M;
V_old = V;
M = M(~inds_to_rem);
V = V(~inds_to_rem,:);
end
num_points = numel(M) / 3;
m = reshape(M, num_points, 3)';
width_model = max(m(1,:)) - min(m(1,:));
height_model = max(m(2,:)) - min(m(2,:));
bounding_box = [min(shape2D(:,1)), min(shape2D(:,2)),...
max(shape2D(:,1)), max(shape2D(:,2))];
a = (((bounding_box(3) - bounding_box(1)) / width_model) + ((bounding_box(4) - bounding_box(2))/ height_model)) / 2;
tx = (bounding_box(3) + bounding_box(1))/2;
ty = (bounding_box(4) + bounding_box(2))/2;
% correct it so that the bounding box is just around the minimum
% and maximum point in the initialised face
tx = tx - a*(min(m(1,:)) + max(m(1,:)))/2;
ty = ty - a*(min(m(2,:)) + max(m(2,:)))/2;
R = eye(3);
T = [tx; ty];
currShape = getShapeOrtho(M, V, params, R, T, a);
currError = getRMSerror(currShape, shape2D);
reg_rigid = zeros(6,1);
regFactor = 20;
regularisations = [reg_rigid; regFactor ./ E]; % the above version, however, does not perform as well
regularisations = diag(regularisations)*diag(regularisations);
red_in_a_row = 0;
for i=1:1000
shape3D = M + V * params;
shape3D = reshape(shape3D, numel(shape3D) / 3, 3);
% Now find the current residual error
currShape = a * R(1:2,:)*shape3D' + repmat(T, 1, numel(M)/3);
currShape = currShape';
error_res = shape2D - currShape;
eul = Rot2Euler(R);
p_global = [a; eul'; T];
% get the Jacobians
J = CalcJacobian(M, V, params, p_global);
% RLMS style update
p_delta = (J'*J + regularisations) \ (J'*error_res(:) - regularisations*[p_global;params]);
[params, p_global] = CalcReferenceUpdate(p_delta, params, p_global);
a = p_global(1);
R = Euler2Rot(p_global(2:4));
T = p_global(5:6);
shape3D = M + V * params;
shape3D = reshape(shape3D, numel(shape3D) / 3, 3);
currShape = a * R(1:2,:)*shape3D' + repmat(T, 1, numel(M)/3);
currShape = currShape';
error = getRMSerror(currShape, shape2D);
if(0.999 * currError < error)
red_in_a_row = red_in_a_row + 1;
if(red_in_a_row == 5)
break;
end
end
currError = error;
end
if(hidden)
shapeOrtho = getShapeOrtho(M_old, V_old, params, R, T, a);
else
shapeOrtho = currShape;
end
if(nargin == 7)
Zavg = f / a;
Xavg = (T(1) - cx) / a;
Yavg = (T(2) - cy) / a;
T3D = [Xavg;Yavg;Zavg];
else
T3D = [0;0;0];
end
end
function [shape2D] = getShapeOrtho(M, V, p, R, T, a)
% M - mean shape vector
% V - eigenvectors
% p - parameters of non-rigid shape
% R - rotation matrix
% T - translation vector (tx, ty)
shape3D = getShape3D(M, V, p);
shape2D = a * R(1:2,:)*shape3D' + repmat(T, 1, numel(M)/3);
shape2D = shape2D';
end
function [shape2D] = getShapeOrthoFull(M, V, p, R, T, a)
% M - mean shape vector
% V - eigenvectors
% p - parameters of non-rigid shape
% R - rotation matrix
% T - translation vector (tx, ty)
T = [T; 0];
shape3D = getShape3D(M, V, p);
shape2D = a * R*shape3D' + repmat(T, 1, numel(M)/3);
shape2D = shape2D';
end
function [shape3D] = getShape3D(M, V, params)
shape3D = M + V * params;
shape3D = reshape(shape3D, numel(shape3D) / 3, 3);
end
function [error] = getRMSerror(shape2Dv1, shape2Dv2)
error = sqrt(mean(reshape(shape2Dv1 - shape2Dv2, numel(shape2Dv1), 1).^2));
end
% This calculates the combined rigid with non-rigid Jacobian
function J = CalcJacobian(M, V, p, p_global)
n = size(M, 1)/3;
non_rigid_modes = size(V,2);
J = zeros(n*2, 6 + non_rigid_modes);
% now the layour is
% ---------- Rigid part -------------------|----Non rigid part--------|
% dx_1/ds, dx_1/dr1, ... dx_1/dtx, dx_1/dty dx_1/dp_1 ... dx_1/dp_m
% dx_2/ds, dx_2/dr1, ... dx_2/dtx, dx_2/dty dx_2/dp_1 ... dx_2/dp_m
% ...
% dx_n/ds, dx_n/dr1, ... dx_n/dtx, dx_n/dty dx_n/dp_1 ... dx_n/dp_m
% dy_1/ds, dy_1/dr1, ... dy_1/dtx, dy_1/dty dy_1/dp_1 ... dy_1/dp_m
% ...
% dy_n/ds, dy_n/dr1, ... dy_n/dtx, dy_n/dty dy_n/dp_1 ... dy_n/dp_m
% getting the rigid part
J(:,1:6) = CalcRigidJacobian(M, V, p, p_global);
% constructing the non-rigid part
R = Euler2Rot(p_global(2:4));
s = p_global(1);
% 'rotate' and 'scale' the principal components
% First reshape to 3D
V_X = V(1:n,:);
V_Y = V(n+1:2*n,:);
V_Z = V(2*n+1:end,:);
J_x_non_rigid = s*(R(1,1)*V_X + R(1,2)*V_Y + R(1,3)*V_Z);
J_y_non_rigid = s*(R(2,1)*V_X + R(2,2)*V_Y + R(2,3)*V_Z);
J(1:n, 7:end) = J_x_non_rigid;
J(n+1:end, 7:end) = J_y_non_rigid;
end
function J = CalcRigidJacobian(M, V, p, p_global)
n = size(M, 1)/3;
% Get the current 3D shape (not affected by global transform, as this
% is how the Jacobian was derived (for derivation please see
% ../derivations/orthoJacobian
shape3D = GetShape3D(M, V, p);
% Get the rotation matrix corresponding to current global orientation
R = Euler2Rot(p_global(2:4));
s = p_global(1);
% Rigid Jacobian is laid out as follows
% dx_1/ds, dx_1/dr1, dx_1/dr2, dx_1/dr3, dx_1/dtx, dx_1/dty
% dx_2/ds, dx_2/dr1, dx_2/dr2, dx_2/dr3, dx_2/dtx, dx_2/dty
% ...
% dx_n/ds, dx_n/dr1, dx_n/dr2, dx_n/dr3, dx_n/dtx, dx_n/dty
% dy_1/ds, dy_1/dr1, dy_1/dr2, dy_1/dr3, dy_1/dtx, dy_1/dty
% ...
% dy_n/ds, dy_n/dr1, dy_n/dr2, dy_n/dr3, dy_n/dtx, dy_n/dty
J = zeros(n*2, 6);
% dx/ds = X * r11 + Y * r12 + Z * r13
% dx/dr1 = s*(r13 * Y - r12 * Z)
% dx/dr2 = -s*(r13 * X - r11 * Z)
% dx/dr3 = s*(r12 * X - r11 * Y)
% dx/dtx = 1
% dx/dty = 0
% dy/ds = X * r21 + Y * r22 + Z * r23
% dy/dr1 = s * (r23 * Y - r22 * Z)
% dy/dr2 = -s * (r23 * X - r21 * Z)
% dy/dr3 = s * (r22 * X - r21 * Y)
% dy/dtx = 0
% dy/dty = 1
% set the Jacobian for x's
% with respect to scaling factor
J(1:n,1) = shape3D * R(1,:)';
% with respect to angular rotation around x, y, and z axes
% Change of x with respect to change in axis angle rotation
dxdR = [ 0, R(1,3), -R(1,2);
-R(1,3), 0, R(1,1);
R(1,2), -R(1,1), 0];
J(1:n,2:4) = s*(dxdR * shape3D')';
% with respect to translation
J(1:n,5) = 1;
J(1:n,6) = 0;
% set the Jacobian for y's
% with respect to scaling factor
J(n+1:end,1) = shape3D * R(2,:)';
% with respect to angular rotation around x, y, and z axes
% Change of y with respect to change in axis angle rotation
dydR = [ 0, R(2,3), -R(2,2);
-R(2,3), 0, R(2,1);
R(2,2), -R(2,1), 0];
J(n+1:end,2:4) = s*(dydR * shape3D')';
% with respect to translation
J(n+1:end,5) = 0;
J(n+1:end,6) = 1;
end
% This updates the parameters based on the updates from the RLMS
function [non_rigid, rigid] = CalcReferenceUpdate(params_delta, current_non_rigid, current_global)
rigid = zeros(6, 1);
% Same goes for scaling and translation parameters
rigid(1) = current_global(1) + params_delta(1);
rigid(5) = current_global(5) + params_delta(5);
rigid(6) = current_global(6) + params_delta(6);
% for rotation however, we want to make sure that the rotation matrix
% approximation we have
% R' = [1, -wz, wy
% wz, 1, -wx
% -wy, wx, 1]
% is a legal rotation matrix, and then we combine it with current
% rotation (through matrix multiplication) to acquire the new rotation
R = Euler2Rot(current_global(2:4));
wx = params_delta(2);
wy = params_delta(3);
wz = params_delta(4);
R_delta = [1, -wz, wy;
wz, 1, -wx;
-wy, wx, 1];
% Make sure R_delta is orthonormal
R_delta = OrthonormaliseRotation(R_delta);
% Combine rotations
R_final = R * R_delta;
% Extract euler angle
euler = Rot2Euler(R_final);
rigid(2:4) = euler;
if(length(params_delta) > 6)
% non-rigid parameters can just be added together
non_rigid = params_delta(7:end) + current_non_rigid;
else
non_rigid = current_non_rigid;
end
end
function R_ortho = OrthonormaliseRotation(R)
% U * V' is basically what we want, as it's guaranteed to be
% orthonormal
[U, ~, V] = svd(R);
% We also want to make sure no reflection happened
% get the orthogonal matrix from the initial rotation matrix
X = U*V';
% This makes sure that the handedness is preserved and no reflection happened
% by making sure the determinant is 1 and not -1
W = eye(3);
W(3,3) = det(X);
R_ortho = U*W*V';
end

View File

@@ -0,0 +1,32 @@
function [ pts_new ] = iterate_piece_wise( pts_orig, new_num_points )
%ITERATE_PIECE_WISE Summary of this function goes here
% Detailed explanation goes here
% Reinterpolate the new points, but make sure they are still on the
% same lines
num_orig = size(pts_orig,1);
% Divide the number of original segments by number of new segments
step_size = (num_orig - 1) / (new_num_points-1);
pts_new = zeros(new_num_points,2);
% Clamp the beginning and end, as they will be the same
pts_new(1,:) = pts_orig(1,:);
pts_new(end,:) = pts_orig(end,:);
for i=1:new_num_points-2
low_point = floor(1 + i * step_size);
high_point = ceil(1 + i * step_size);
coeff_1 = floor(1 + i * step_size) - i * step_size;
coeff_2 = 1 - coeff_1;
new_pt = coeff_1 * pts_orig(low_point,:) + coeff_2 * pts_orig(high_point,:);
pts_new(i+1,:) = new_pt;
end
end

View File

@@ -0,0 +1,16 @@
% for easier readibility write them row by row
function writeMatrix(fileID, M, type)
fprintf(fileID, '%d\r\n', size(M,1));
fprintf(fileID, '%d\r\n', size(M,2));
fprintf(fileID, '%d\r\n', type);
for i=1:size(M,1)
if(type == 4 || type == 0)
fprintf(fileID, '%d ', M(i,:));
else
fprintf(fileID, '%.9f ', M(i,:));
end
fprintf(fileID, '\r\n');
end
end

View File

@@ -0,0 +1,195 @@
% Convert the training images into a suitable format
function Prepare_data_COFW()
% replace with folder where you downloaded and extracted the 300-W challenge data
data_root = '../../../../CLM-framework/matlab_version/occlusion_experiments/data/';
PrepareTrainingWild(data_root, 0.25);
PrepareTrainingWild(data_root, 0.35);
PrepareTrainingWild(data_root, 0.5);
end
function PrepareTrainingWild( data_root, training_scale )
%PREPARETRAININGIMAGEMPIE Summary of this function goes here
% Detailed explanation goes here
% img size
imgSize = [400, 400] * training_scale;
%%
addpath('PDM_helpers/');
load 'PDM_helpers/pdm_29_cofw_aligned.mat';
output_location = '../prepared_data/cofw_';
output_location = [output_location num2str(training_scale,3)];
num_landmarks = 29;
% Use mirror images to provide extra training data
mirror_inds = [1,2; 3,4; 5,7; 6,8; 9,10; 11,12; 13,15; 14,16; 17,18; 19,20; 23,24];
% The centres of views we want to extract
centres_all = [ 0, 0, 0 ];
num_centers = size(centres_all, 1);
counter_colour = zeros(num_centers,1);
load([data_root, '/COFW_train.mat']);
% go through all images, see which centres they match and then add to
% the appropriate bin
num_imgs = numel(IsTr);
scales = zeros(num_imgs, 1);
views = zeros(num_imgs, 1);
for lbl=1:num_imgs
Msm = M;
Vsm = V;
labels = reshape(phisTr(lbl,1:num_landmarks*2), num_landmarks, 2);
% Find the best PDM parameters given the 2D labels
[ a, R] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
eul = Rot2Euler(R);
eul = eul * 180 / pi;
% find the closest view
[~, view] = min(sum(abs(centres_all - repmat(eul, num_centers, 1)),2));
counter_colour(view) = counter_colour(view) + 1;
scales(lbl) = a;
views(lbl) = view;
end
% preallocate data
allExamplesColourAllViews = cell(size(centres_all,1),1);
landmarkLocationsAllViews = cell(size(centres_all,1),1);
occlusionsAllViews = cell(size(centres_all,1),1);
for r=1:size(centres_all,1)
allExamplesColourAllViews{r} = zeros(counter_colour(r), imgSize(1), imgSize(2));
landmarkLocationsAllViews{r} = zeros(counter_colour(r), num_landmarks, 2);
occlusionsAllViews{r} = zeros(counter_colour(r), num_landmarks);
actual_imgs_used_all_views{r} = cell(counter_colour(r), 1);
end
counter_colour = zeros(num_centers,1);
% go through all images and add to corresponding container
for lbl=1:num_imgs
labels = reshape(phisTr(lbl,1:num_landmarks*2), num_landmarks, 2);
occlusions = phisTr(lbl,(num_landmarks*2+1):end);
imgCol = IsTr{lbl};
if(size(imgCol,3) == 3)
imgCol = rgb2gray(imgCol);
end
% resize the image to desired scale
scalingFactor = training_scale / scales(lbl);
resizeColImage = imresize(imgCol, scalingFactor, 'bilinear');
labels = labels * scalingFactor;
% we want to crop out the image now
meanX = round(mean(labels(:,1)));
meanY = round(mean(labels(:,2)));
startX = round(meanX-imgSize(1)/2);
startY = round(meanY-imgSize(2)/2);
if(startX < 1)
startX = 1;
end
if(startY < 1)
startY = 1;
end
endX = startX + imgSize(1) - 1;
endY = startY + imgSize(2) - 1;
if(endX > size(resizeColImage,2))
resizeColImage = cat(2, resizeColImage, zeros(size(resizeColImage,1), endX - size(resizeColImage,2)));
end
if(endY > size(resizeColImage,1))
resizeColImage = cat(1, resizeColImage, zeros(endY - size(resizeColImage,1), size(resizeColImage,2)));
end
resizeColImage = resizeColImage(startY:endY,startX:endX);
labels(:,1) = labels(:,1) - startX + 1;
labels(:,2) = labels(:,2) - startY + 1;
counter_colour(views(lbl)) = counter_colour(views(lbl)) + 1;
allExamplesColourAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = resizeColImage;
landmarkLocationsAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = labels;
occlusionsAllViews{views(lbl)}(counter_colour(views(lbl)),:) = occlusions;
actual_imgs_used_all_views{views(lbl)}{counter_colour(views(lbl))} = 'placeholder';
if(mod(lbl, 100) == 0)
fprintf('%d/%d done\n', lbl, num_imgs);
end
end
% write out the training data for each view
for r=1:size(centres_all,1)
mirrorIdx = find(sum(abs(centres_all - repmat([centres_all(r,1), -centres_all(r,2), -centres_all(r,3)], size(centres_all,1),1)),2)==0);
% if the mirrored view already added no need to do it again
% so if (0,-20,0) is done no need to compute (0,20,0)
if(mirrorIdx < r)
continue
end
mirrorImgs = allExamplesColourAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
mirrorLbls = landmarkLocationsAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
mirrorOccls = occlusionsAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:);
for i=1:size(mirrorImgs,1)
flippedImg = fliplr(squeeze(mirrorImgs(i,:,:)));
flippedLbls = squeeze(mirrorLbls(i,:,:));
flippedLbls(:,1) = imgSize(1) - flippedLbls(:,1);
tmp1 = flippedLbls(mirror_inds(:,1),:);
tmp2 = flippedLbls(mirror_inds(:,2),:);
flippedLbls(mirror_inds(:,2),:) = tmp1;
flippedLbls(mirror_inds(:,1),:) = tmp2;
mirrorImgs(i,:,:) = flippedImg;
mirrorLbls(i,:,:) = flippedLbls;
tmp1 = mirrorOccls(i,mirror_inds(:,1));
tmp2 = mirrorOccls(i,mirror_inds(:,2));
mirrorOccls(i,mirror_inds(:,1)) = tmp2;
mirrorOccls(i,mirror_inds(:,2)) = tmp1;
end
all_images = cat(1, allExamplesColourAllViews{r}(1:counter_colour(r),:,:), mirrorImgs);
all_images = uint8(all_images);
landmark_locations = cat(1, landmarkLocationsAllViews{r}(1:counter_colour(r),:,:), mirrorLbls);
occlusions = cat(1, occlusionsAllViews{r}(1:counter_colour(r),:), mirrorOccls);
actual_imgs_used = actual_imgs_used_all_views{r};
actual_imgs_used = cat(1, actual_imgs_used_all_views{r}, actual_imgs_used_all_views{mirrorIdx});
centres = centres_all(r,:);
visiIndex = ones(1,num_landmarks);
save([output_location '_' num2str(r) '.mat'], 'all_images', 'occlusions', 'landmark_locations', 'training_scale', 'actual_imgs_used', 'centres', 'visiIndex', '-v7.3');
end
end

View File

@@ -0,0 +1,499 @@
function Prepare_data_Multi_PIE_all()
% This bit collects all of the multi-pie labels into a single structure for
% easy access
labels_root = 'C:\Users\tbaltrus\Dropbox\AAM\test data\MultiPI_AAM/';
% The location of the Multi-PIE data folder
multi_pie_root = 'D:\MultiPIE/Image_Data/';
multi_pie_labels = CollectMultiPieLabels(labels_root, multi_pie_root);
%%
% Make sure same images are used across scales
rng(0);
ExtractTrainingMultiPIE(0.25, multi_pie_labels);
rng(0);
ExtractTrainingMultiPIE(0.35, multi_pie_labels);
rng(0);
ExtractTrainingMultiPIE(0.5, multi_pie_labels);
rng(0);
ExtractTrainingMultiPIE(1.0, multi_pie_labels);
end
% Now extract the relevant information
function [multi_pie_labels] = CollectMultiPieLabels(labels_root, multi_pie_root)
multi_pie_labels = struct;
currentLabel = 0;
left_to_frontal_map = [1, 28;
2, 29;
3, 30;
4, 31;
5, 34;
6, 36;
7, 27;
8, 26;
9, 25;
10,24;
11,46;
12,45;
13,44;
14,48;
15,47;
16,52;
17,53;
18,54;
19,55;
20,56;
21,57;
22,58;
23,63;
24,64;
26,66;
27,67;
30,9;
31,10;
32,11;
33,12;
34,13;
35,14;
36,15;
37,16;
38,17;];
right_to_frontal_map = [1, 28;
2, 29;
3, 30;
4, 31;
5, 34;
6, 32;
7 ,18;
8 ,19;
9 ,20;
10,21;
11,37;
12,38;
13,39;
14,41;
15,42;
16,52;
17,51;
18,50;
19,49;
20,60;
21,59;
22,58;
23,63;
24,62;
26,68;
27,67;
30, 9;
31, 8;
32, 7;
33, 6;
34, 5;
35, 4;
36, 3;
37, 2;
38, 1];
for i=1:4
labelsDir = sprintf('%sSession%d/', labels_root, i);
labels = dir([labelsDir '/*.mat']);
double_label = false;
for j = 1:numel(labels)
if(double_label)
double_label = false;
continue;
end
load([labelsDir labels(j).name]);
if(size(pts,1) ~= 68 && size(pts,1) ~= 39)
continue;
end
userID = labels(j).name(1:3);
recID = labels(j).name(8:9);
camID = labels(j).name(11:12);
camID2 = labels(j).name(13);
viewID = labels(j).name(15:16);
% doubling labels seem to be odd/incorrect
if(j < numel(labels))
userIDN = labels(j+1).name(1:3);
recIDN = labels(j+1).name(8:9);
camIDN = labels(j+1).name(11:12);
camID2N = labels(j+1).name(13);
if(strcmp(userIDN, userID) && strcmp(recID, recIDN) && strcmp(camIDN, camID) && strcmp(camID2N, camID2))
double_label = true;
continue;
end
end
% camera id 08 is from a very different perspective
if(strcmp(camID, '08') && strcmp(camID2, '1'))
continue;
end
currentLabel = currentLabel + 1;
multi_pie_labels(currentLabel).label_file = [labelsDir labels(j).name];
multi_pie_labels(currentLabel).user_ID = userID;
multi_pie_labels(currentLabel).rec_ID = recID;
multi_pie_labels(currentLabel).cam_ID = camID;
multi_pie_labels(currentLabel).cam_ID2 = camID2;
multiPieImageDir = sprintf('%s/session0%d/multiview/%s/%s/%s_%s/', multi_pie_root, i,userID,recID,camID,camID2);
multiPieImgs = dir([multiPieImageDir '*.png']);
multi_pie_labels(currentLabel).img_dir = multiPieImageDir;
% multi_pie_labels(currentLabel).img_loc = [labels(j+1).name(1:end-7), '.png'];
actualLabel = dir([multiPieImageDir '/*' viewID '.png']);
multi_pie_labels(currentLabel).img_locs = {multiPieImgs.name};
multi_pie_labels(currentLabel).actual_img = actualLabel.name;
landmark_labels = zeros(68,2);
% This is a profile image
if(size(pts,1) == 39)
% Determine if left or right
if(pts(4,1) < pts(39,1))
multi_pie_labels(currentLabel).type = 'profile_left';
landmark_labels(left_to_frontal_map(:,2),:) = pts(left_to_frontal_map(:,1),:);
else
multi_pie_labels(currentLabel).type = 'profile_right';
landmark_labels(right_to_frontal_map(:,2),:) = pts(right_to_frontal_map(:,1),:);
end
else
landmark_labels = pts;
end
multi_pie_labels(currentLabel).landmark_labels = landmark_labels;
end
end
end
function ExtractTrainingMultiPIE( training_scale, multi_pie_labels)
%PREPARETRAININGIMAGEMPIE This function collects a subset of Multi-PIE
%images at different expressions and lighting conditions to store it in a
%format suitable for training patch experts
% Detailed explanation goes here
img_size = [400, 400] * training_scale;
%%
addpath('PDM_helpers/');
load 'PDM_helpers/pdm_68_aligned_wild.mat';
output_location = '../prepared_data/mpie_';
output_location = [output_location num2str(training_scale,3)];
num_landmarks = 68;
% Use mirror images to provide extra training data
mirror_inds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
% The centres of views we want to extract
centres_all = [ 0, 0, 0
0, -20, 0
0, -45, 0
0, -70, 0
0, 20, 0
0, 45, 0
0, 70, 0
];
num_centers = size(centres_all, 1);
counter_colour = zeros(num_centers,1);
% read in all of the labels, together with names of images used
landmark_labels = zeros(68,2,numel(multi_pie_labels));
img_locations = cell(numel(multi_pie_labels),1);
extra_locations = cell(numel(multi_pie_labels),1);
img_dirs = cell(numel(multi_pie_labels),1);
for i=1:numel(multi_pie_labels)
img_locations{i} = [multi_pie_labels(i).img_dir, multi_pie_labels(i).actual_img];
extra_locations{i} = multi_pie_labels(i).img_locs;
img_dirs{i} = multi_pie_labels(i).img_dir;
landmark_labels(:,:,i) = multi_pie_labels(i).landmark_labels;
end
% go through all images, see which centres they match and then add to
% the appropriate bin
num_imgs = size(landmark_labels,3);
scales = zeros(num_imgs, 1);
views = zeros(num_imgs, 1);
for lbl=1:num_imgs
Msm = M;
Vsm = V;
labels = landmark_labels(:,:,lbl);
% Find the best PDM parameters given the 2D labels
[ a,R ] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
eul = Rot2Euler(R);
eul_orig = eul * 180 / pi;
if(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '24_0'))
eul = [0, -90, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '01_0'))
eul = [0, -75, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '20_0'))
eul = [0, -60, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '19_0'))
eul = [0, -45, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '04_1'))
eul = [0, -30, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '05_0'))
eul = [0, -15, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '05_1'))
eul = [0, 0, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '14_0'))
eul = [0, 15, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '13_0'))
eul = [0, 30, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '08_0'))
eul = [0, 45, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '09_0'))
eul = [0, 60, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '12_0'))
eul = [0, 75, 0];
elseif(strcmp([multi_pie_labels(lbl).cam_ID,'_', multi_pie_labels(lbl).cam_ID2], '11_0'))
eul = [0, 90, 0];
end
% find the closest view (also mirror img?)
[~, view] = min(sum(abs(centres_all - repmat(eul, num_centers, 1)),2));
counter_colour(view) = counter_colour(view) + 1;
scales(lbl) = a;
views(lbl) = view;
end
% preallocate data
allExamplesColourAllViews = cell(size(centres_all,1),1);
landmarkLocationsAllViews = cell(size(centres_all,1),1);
% if we don't have enough labelled original images add ones from diff
% lighting conditions (that might not be perfectly labelled, but they
% are better than fewer images)
images_aim = 8000;
extra_factors = ones(size(counter_colour));
for r=1:size(centres_all,1)
% see if extra is needed
mirrorIdx = find(sum(abs(centres_all - repmat([centres_all(r,1), -centres_all(r,2), -centres_all(r,3)], size(centres_all,1),1)),2)==0);
count = counter_colour(r) + counter_colour(mirrorIdx);
if(count < images_aim)
extra_factors(r) = images_aim / count;
end
end
for r=1:size(centres_all,1)
counter_colour(r) = round(counter_colour(r) * extra_factors(r));
allExamplesColourAllViews{r} = uint8(zeros(counter_colour(r), img_size(1), img_size(2)));
landmarkLocationsAllViews{r} = zeros(counter_colour(r), num_landmarks, 2);
actual_imgs_used_all_views{r} = cell(counter_colour(r), 1);
end
counter_colour = zeros(num_centers,1);
% The shape fitting is performed in the reference frame of the
% patch training scale
refGlobal = [training_scale, 0, 0, 0, 0, 0]';
% go through all images and add to corresponding container
for lbl=1:num_imgs
labels = landmark_labels(:,:,lbl);
occluded = labels(:,1) == 0;
% Convert the labels to matlab format (we expect 1,1 to represent
% the center of the top left pixel)
labels = labels + 1;
labels(occluded,:) = 0;
imgCol = imread(img_locations{lbl});
if(size(imgCol,3) == 3)
imgCol = rgb2gray(imgCol);
end
% the reference shape
[ ~, ~, ~,~, local_params] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
refShape = GetShapeOrtho(M, Vsm, local_params, refGlobal);
% Create transform using a slightly modified version of Kabsch that
% takes scaling into account as well, in essence we get a
% similarity transform from current estimate to reference shape
[A_img2ref, T_img2ref, ~, ~] = AlignShapesWithScale(labels(~occluded,:), refShape(~occluded,1:2));
T_img2ref = T_img2ref + [img_size(1)/2, img_size(2)/2];
% Create a transform, from shape in image to reference shape
T = affine2d([A_img2ref';T_img2ref]);
% transform the current shape to the reference one
shape2D_in_ref = bsxfun(@plus, (A_img2ref * labels')', T_img2ref);
% warp the image
resizeColImage = imwarp(imgCol, T, 'linear', 'OutputView', imref2d(img_size));
shape2D_in_ref(occluded,1) = 0;
shape2D_in_ref(occluded,2) = 0;
counter_colour(views(lbl)) = counter_colour(views(lbl)) + 1;
allExamplesColourAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = resizeColImage;
landmarkLocationsAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = shape2D_in_ref;
actual_imgs_used_all_views{views(lbl)}{counter_colour(views(lbl))} = img_locations{lbl};
% Here to add extra images if missing and not filled yet
if(extra_factors(views(lbl)) > 1 && counter_colour(views(lbl)) < numel(actual_imgs_used_all_views{views(lbl)}))
factor = extra_factors(views(lbl));
% pick if to use this image or not
if(randi(100) > (factor - floor(factor)) * 100)
factor = floor(factor);
else
factor = ceil(factor);
end
while(factor > 1)
lighting_id = randi(20);
[~, img_orig, ext] = fileparts(img_locations{lbl});
img_orig = [img_orig, ext];
if( strcmp(img_orig, extra_locations{lbl}{lighting_id}))
lighting_id = lighting_id + 1;
if(lighting_id > 20)
lighting_id = 1;
end
end
img_loc = [img_dirs{lbl}, extra_locations{lbl}{lighting_id}];
imgCol = imread(img_loc);
if(size(imgCol,3) == 3)
imgCol = rgb2gray(imgCol);
end
% resize the image to desired scale
resizeColImage = imwarp(imgCol, T, 'linear', 'OutputView', imref2d(img_size));
counter_colour(views(lbl)) = counter_colour(views(lbl)) + 1;
allExamplesColourAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = resizeColImage;
landmarkLocationsAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = shape2D_in_ref;
actual_imgs_used_all_views{views(lbl)}{counter_colour(views(lbl))} = img_loc;
factor = factor - 1;
end
end
% Make sure same one not added as well
if(mod(lbl, 100) == 0)
fprintf('%d/%d done\n', lbl, num_imgs);
end
end
% write out the training data for each view
for r=1:size(centres_all,1)
mirrorIdx = find(sum(abs(centres_all - repmat([centres_all(r,1), -centres_all(r,2), -centres_all(r,3)], size(centres_all,1),1)),2)==0);
% if the mirrored view already added no need to do it again
% so if (0,-20,0) is done no need to compute (0,20,0)
if(mirrorIdx < r)
continue
end
% Cap to two thousand images for space reasons, and because more
% wouldn't actually be used
max_images = 2000;
mirrorImgs = allExamplesColourAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
mirrorLbls = landmarkLocationsAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
for i=1:size(mirrorImgs,1)
flippedImg = fliplr(squeeze(mirrorImgs(i,:,:)));
flippedLbls = squeeze(mirrorLbls(i,:,:));
flippedLbls(:,1) = img_size(1) - flippedLbls(:,1) + 1;
tmp1 = flippedLbls(mirror_inds(:,1),:);
tmp2 = flippedLbls(mirror_inds(:,2),:);
flippedLbls(mirror_inds(:,2),:) = tmp1;
flippedLbls(mirror_inds(:,1),:) = tmp2;
mirrorImgs(i,:,:) = flippedImg;
mirrorLbls(i,:,:) = flippedLbls;
% Ensure that after mirroring invalid (occluded) feature points
% are set to 0 in both x and y dims
mirrorLbls(i,flippedLbls(:,2)==0,1) = 0;
end
all_images = cat(1, allExamplesColourAllViews{r}(1:counter_colour(r),:,:), mirrorImgs);
landmark_locations = cat(1, landmarkLocationsAllViews{r}(1:counter_colour(r),:,:), mirrorLbls);
actual_imgs_used = cat(1, actual_imgs_used_all_views{r}(1:counter_colour(r)), actual_imgs_used_all_views{mirrorIdx}(1:counter_colour(mirrorIdx)));
centres = centres_all(r,:);
% identify the visibility of a point
num_visible = sum(landmark_locations(:,:,1)~=0);
visible_max = max(num_visible);
visiIndex = ones(1,68);
visiIndex(num_visible < 0.5*visible_max) = 0;
if(size(all_images,1) > max_images)
im_to_select = randperm(size(all_images,1));
im_to_select = im_to_select(1:max_images);
all_images = all_images(im_to_select,:,:);
landmark_locations = landmark_locations(im_to_select,:,:);
actual_imgs_used = actual_imgs_used(im_to_select);
end
save([output_location '_' num2str(r) '.mat'], 'all_images', 'landmark_locations', 'training_scale', 'centres', 'actual_imgs_used', 'visiIndex', '-v7.3');
end
end

View File

@@ -0,0 +1,48 @@
function Prepare_data_combined_all()
% Read in in-the-wild data and Multi-PIE data and concatenate them
root = '../prepared_data/';
Collect_combined_data(root, '0.25');
Collect_combined_data(root, '0.35');
Collect_combined_data(root, '0.5');
Collect_combined_data(root, '1');
end
function Collect_combined_data(root, scale)
wild_locs = dir(sprintf('%s/wild_%s*.mat', root, scale));
mpie_locs = dir(sprintf('%s/mpie_%s*.mat', root, scale));
% For a particular loaded m_pie check if an appropriate in-the-wild
% exists
for i=1:numel(mpie_locs)
load([root, mpie_locs(i).name]);
imgs_used_pie = actual_imgs_used;
samples_pie = all_images;
centres_pie = centres;
landmark_locations_pie = landmark_locations;
wild_to_use = -1;
for j=1:numel(wild_locs)
load([root, wild_locs(j).name], 'centres');
if(isequal(centres_pie, centres))
wild_to_use = j;
end
end
% Reset the centres
centres = centres_pie;
if(wild_to_use ~= -1)
load([root, wild_locs(wild_to_use).name]);
actual_imgs_used = cat(1, actual_imgs_used, imgs_used_pie);
all_images = cat(1, all_images, samples_pie);
landmark_locations = cat(1, landmark_locations, landmark_locations_pie);
end
save(sprintf('%s/combined_%s_%d.mat', root, scale, i), 'actual_imgs_used', 'all_images', 'centres', 'landmark_locations', 'training_scale', 'visiIndex');
end
end

View File

@@ -0,0 +1,437 @@
% Convert the training images into a suitable format
function Prepare_data_menpo_all()
% replace with folder where you downloaded and extracted the 300-W challenge data
data_root_train = 'C:\Users\tbaltrus\Documents\menpo_data_orig\train/';
PrepareTrainingMenpo(data_root_train, 0.25, 'train');
PrepareTrainingMenpo(data_root_train, 0.35, 'train');
PrepareTrainingMenpo(data_root_train, 0.5, 'train');
PrepareTrainingMenpo(data_root_train, 1.0, 'train');
data_root_valid = 'C:\Users\tbaltrus\Documents\menpo_data_orig\valid/';
PrepareTrainingMenpo(data_root_valid, 0.25, 'valid');
PrepareTrainingMenpo(data_root_valid, 0.35, 'valid');
PrepareTrainingMenpo(data_root_valid, 0.5, 'valid');
PrepareTrainingMenpo(data_root_valid, 1.0, 'valid');
end
function PrepareTrainingMenpo( data_root, training_scale, postfix )
%PREPARETRAININGIMAGEMPIE Summary of this function goes here
% Detailed explanation goes here
% img size
imgSize = [400, 400] * training_scale;
%%
addpath('PDM_helpers/');
load 'PDM_helpers/pdm_68_aligned_menpo_v5.mat';
output_location = ['../prepared_data/menpo_', postfix, '_'];
output_location = [output_location num2str(training_scale,3)];
num_landmarks = 68;
% Use mirror images to provide extra training data
mirror_inds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
% The centres of views we want to extract
centres_all = [ 0, 0, 0
0, -20, 0
0, -45, 0
0, -70, 0
0, 20, 0
0, 45, 0
0, 70, 0
];
num_centers = size(centres_all, 1);
counter_colour = zeros(num_centers,1);
img_locations = {};
% read in all of the labels, together with names of images used
curr_labels = dir([data_root '\*.pts']);
imgs = dir([data_root '\*.jpg']);
if(isempty(imgs))
imgs = dir([data_root '\*.png']);
end
landmark_labels = zeros(68, 2, numel(curr_labels));
for p=1:numel(curr_labels)
landmarks_c = importdata([data_root, curr_labels(p).name], ' ', 3);
landmarks_c = landmarks_c.data;
% Correct landmarks if needed
[new_landmarks] = correctLandmarks(landmarks_c, imgs(p).name);
% Map the profile ones to proper ones
[landmark_labels_c] = standardiseLandmarks(new_landmarks);
landmark_labels(:,:,p) = landmark_labels_c;
img_locations = cat(1, img_locations, [data_root imgs(p).name]);
end
% go through all images, see which centres they match and then add to
% the appropriate bin
num_imgs = size(landmark_labels,3);
scales = zeros(num_imgs, 1);
views = zeros(num_imgs, 1);
for lbl=1:num_imgs
Msm = M;
Vsm = V;
labels = landmark_labels(:,:,lbl);
% Find the best PDM parameters given the 2D labels
[ a, R] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
eul = Rot2Euler(R);
eul = eul * 180 / pi;
% find the closest view
[~, view] = min(sum(abs(centres_all - repmat(eul, num_centers, 1)),2));
counter_colour(view) = counter_colour(view) + 1;
scales(lbl) = a;
views(lbl) = view;
end
% preallocate data
allExamplesColourAllViews = cell(size(centres_all,1),1);
landmarkLocationsAllViews = cell(size(centres_all,1),1);
for r=1:size(centres_all,1)
allExamplesColourAllViews{r} = uint8(zeros(counter_colour(r), imgSize(1), imgSize(2)));
landmarkLocationsAllViews{r} = zeros(counter_colour(r), num_landmarks, 2);
actual_imgs_used_all_views{r} = cell(counter_colour(r), 1);
end
counter_colour = zeros(num_centers,1);
% The shape fitting is performed in the reference frame of the
% patch training scale
refGlobal = [training_scale, 0, 0, 0, 0, 0]';
% go through all images and add to corresponding container
for lbl=1:num_imgs
% shift the pixels to be centered on pixel as opposed to top left
occluded = landmark_labels(:,1,lbl) == 0;
labels = landmark_labels(:,:,lbl) - 0.5;
labels(occluded,:) = 0;
imgCol = imread(img_locations{lbl});
if(size(imgCol,3) == 3)
imgCol = rgb2gray(imgCol);
end
% the reference shape
[ ~, ~, ~,~, local_params] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
refShape = GetShapeOrtho(M, Vsm, local_params, refGlobal);
% Create transform using a slightly modified version of Kabsch that
% takes scaling into account as well, in essence we get a
% similarity transform from current estimate to reference shape
[A_img2ref, T_img2ref, ~, ~] = AlignShapesWithScale(labels(~occluded,:), refShape(~occluded,1:2));
T_img2ref = T_img2ref + [imgSize(1)/2, imgSize(2)/2];
% Create a transform, from shape in image to reference shape
T = affine2d([A_img2ref';T_img2ref]);
% transform the current shape to the reference one
shape2D_in_ref = bsxfun(@plus, (A_img2ref * labels')', T_img2ref);
shape2D_in_ref(occluded,:) = 0;
% warp the image
[warped_img] = imwarp(imgCol, T, 'linear', 'OutputView', imref2d(imgSize));
counter_colour(views(lbl)) = counter_colour(views(lbl)) + 1;
allExamplesColourAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = warped_img;
landmarkLocationsAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = shape2D_in_ref;
actual_imgs_used_all_views{views(lbl)}{counter_colour(views(lbl))} = img_locations{lbl};
if(mod(lbl, 100) == 0)
fprintf('%d/%d done\n', lbl, num_imgs);
end
end
% write out the training data for each view
for r=1:size(centres_all,1)
mirrorIdx = find(sum(abs(centres_all - repmat([centres_all(r,1), -centres_all(r,2), -centres_all(r,3)], size(centres_all,1),1)),2)==0);
% if the mirrored view already added no need to do it again
% so if (0,-20,0) is done no need to compute (0,20,0)
if(mirrorIdx < r)
continue
end
mirrorImgs = allExamplesColourAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
mirrorLbls = landmarkLocationsAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
for i=1:size(mirrorImgs,1)
flippedImg = fliplr(squeeze(mirrorImgs(i,:,:)));
flippedLbls = squeeze(mirrorLbls(i,:,:));
flippedLbls(:,1) = imgSize(1) - flippedLbls(:,1) + 1;
tmp1 = flippedLbls(mirror_inds(:,1),:);
tmp2 = flippedLbls(mirror_inds(:,2),:);
flippedLbls(mirror_inds(:,2),:) = tmp1;
flippedLbls(mirror_inds(:,1),:) = tmp2;
mirrorImgs(i,:,:) = flippedImg;
mirrorLbls(i,:,:) = flippedLbls;
% Ensure that after mirroring invalid (occluded) feature points
% are set to 0 in both x and y dims
mirrorLbls(i,flippedLbls(:,2)==0,1) = 0;
end
all_images = cat(1, allExamplesColourAllViews{r}(1:counter_colour(r),:,:), mirrorImgs);
landmark_locations = cat(1, landmarkLocationsAllViews{r}(1:counter_colour(r),:,:), mirrorLbls);
actual_imgs_used = actual_imgs_used_all_views{r};
actual_imgs_used = cat(1, actual_imgs_used_all_views{r}, actual_imgs_used_all_views{mirrorIdx});
centres = centres_all(r,:);
% identify the visibility of a point
num_visible = sum(landmark_locations(:,:,1)~=0);
visible_max = max(num_visible);
visiIndex = ones(1,68);
visiIndex(num_visible < 0.5*visible_max) = 0;
save([output_location '_' num2str(r) '.mat'], 'all_images', 'landmark_locations', 'training_scale', 'centres', 'actual_imgs_used', 'visiIndex', '-v7.3');
end
end
function [new_landmarks] = correctLandmarks(landmarks, name)
if(strcmp(name, 'aflw__face_42138.jpg'))
landmarks(23:27,:) = landmarks(27:-1:23,:);
end
if(strcmp(name, 'aflw__face_65193.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_65158.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_65153.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_65119.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64862.jpg'))
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64849.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
end
if(strcmp(name, 'aflw__face_64833.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64806.jpg'))
landmarks([18:22],:) = landmarks(22:-1:18,:);
end
if(strcmp(name, 'aflw__face_64744.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64292.jpg'))
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64170.jpg'))
landmarks([1:12],:) = landmarks(12:-1:1,:);
end
if(strcmp(name, 'aflw__face_64167.jpg'))
landmarks([1:12],:) = landmarks(12:-1:1,:);
end
if(strcmp(name, 'aflw__face_63590.jpg'))
landmarks([18:22],:) = landmarks(22:-1:18,:);
end
if(strcmp(name, 'aflw__face_63190.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_63118.jpg'))
landmarks([1:12],:) = landmarks(12:-1:1,:);
end
if(strcmp(name, 'aflw__face_62990.jpg'))
landmarks([18:22],:) = landmarks(22:-1:18,:);
end
if(strcmp(name, 'aflw__face_62534.jpg'))
landmarks([18:22],:) = landmarks(22:-1:18,:);
end
if(strcmp(name, 'aflw__face_47686.jpg'))
landmarks([64,63,62,61,68,67,66,65],:) = landmarks(61:68,:);
end
if(strcmp(name, 'aflw__face_47687.jpg'))
landmarks([64,63,62,61,68,67,66,65],:) = landmarks(61:68,:);
end
if(strcmp(name, 'aflw__face_45522.jpg'))
outline = landmarks(1:17,:);
outline(12:13,:) = [];
outline = iterate_piece_wise(outline, 17);
landmarks(1:17,:) = outline;
end
if(strcmp(name, 'aflw__face_43536.jpg'))
landmarks(17:22,:) = landmarks(22:-1:17,:);
end
if(strcmp(name, 'aflw__face_42898.jpg'))
landmarks(28:31,:) = landmarks(31:-1:28,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_41716.jpg'))
landmarks(23:27,:) = landmarks(27:-1:23,:);
end
if(strcmp(name, 'aflw__face_41487.jpg'))
landmarks(28:34,:) = landmarks(34:-1:28,:);
end
if(strcmp(name, 'aflw__face_41364.jpg'))
landmarks(37:48,:) = landmarks([43:48, 37:42],:);
end
if(strcmp(name, 'aflw__face_63080.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_63001.jpg'))
landmarks(18:27,:) = landmarks([23:27, 18:22],:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_65249.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_64866.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_64771.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
if(strcmp(name, 'aflw__face_64735.jpg'))
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_64238.jpg'))
landmarks(18:22,:) = landmarks(22:-1:18,:);
end
if(strcmp(name, 'aflw__face_43770.jpg'))
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_63080.jpg'))
landmarks(1:12,:) = landmarks(12:-1:1,:);
landmarks(13:16,:) = landmarks(16:-1:13,:);
end
% Problem with the labels
if(strcmp(name, 'aflw__face_63001.jpg'))
landmarks(18:27,:) = landmarks([23:27, 18:22],:);
end
new_landmarks = landmarks;
end
function [landmark_labels] = standardiseLandmarks(landmarks)
left_to_frontal_map = [17,28; 18,29; 19,30; 20,31;
21,34; 22,32; 23,39; 24,38; 25,37; 26,42; 27,41;
28,52; 29,51; 30,50; 31,49; 32,60; 33,59; 34,58;
35,63; 36,62; 37,61; 38,68; 39,67];
right_to_frontal_map = [17,28; 18,29; 19,30; 20,31;
21,34; 22,36; 23,44; 24,45; 25,46; 26,47; 27,48;
28,52; 29,53; 30,54; 31,55; 32,56; 33,57; 34,58;
35,63; 36,64; 37,65; 38,66; 39,67];
landmark_labels = zeros(68,2);
if(size(landmarks,1) == 39)
% Determine if the points are clock-wise or counter clock-wise
% Clock-wise points are facing left, counter-clock-wise right
sum = 0;
for k=1:11
step = (landmarks(k+1,1) - landmarks(k,1)) * (landmarks(k+1,2) + landmarks(k,2));
sum = sum + step;
end
if(sum > 0)
% First need to resample the face outline as there are 9
% points in the near-frontal and 10 points in profile for
% the outline of the face
outline = iterate_piece_wise(landmarks(1:10,:), 9);
brow = iterate_piece_wise(landmarks(13:16,:), 5);
landmark_labels(1:9,:) = outline;
landmark_labels(18:22,:) = brow;
landmark_labels(left_to_frontal_map(:,2),:) = landmarks(left_to_frontal_map(:,1),:);
else
outline = iterate_piece_wise(landmarks(10:-1:1,:), 9);
brow = iterate_piece_wise(landmarks(16:-1:13,:), 5);
landmark_labels(9:17,:) = outline;
landmark_labels(23:27,:) = brow;
landmark_labels(right_to_frontal_map(:,2),:) = landmarks(right_to_frontal_map(:,1),:);
end
else
landmark_labels = landmarks;
end
end

View File

@@ -0,0 +1,198 @@
% Convert the training images into a suitable format
function Prepare_data_wild_all()
% replace with folder where you downloaded and extracted the 300-W challenge data
data_root = 'C:\Users\tbaltrus\Dropbox\AAM/test data/';
PrepareTrainingWild(data_root, 0.25);
PrepareTrainingWild(data_root, 0.35);
PrepareTrainingWild(data_root, 0.5);
PrepareTrainingWild(data_root, 1.0);
end
function PrepareTrainingWild( data_root, training_scale )
%PREPARETRAININGIMAGEMPIE Summary of this function goes here
% Detailed explanation goes here
% img size
imgSize = [400, 400] * training_scale;
%%
addpath('PDM_helpers/');
load 'PDM_helpers/pdm_68_aligned_wild.mat';
output_location = '../prepared_data/wild_';
output_location = [output_location num2str(training_scale,3)];
num_landmarks = 68;
% Use mirror images to provide extra training data
mirror_inds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
% The centres of views we want to extract
centres_all = [ 0, 0, 0
0, -20, 0
0, 20, 0
];
num_centers = size(centres_all, 1);
counter_colour = zeros(num_centers,1);
% use only 2 of the subsets (others used for testing)
% You just need to provide the location in your system
dataset_locs = { [data_root, '/helen/trainset/'];
[data_root, '/lfpw/trainset/']};
landmark_labels = [];
img_locations = {};
% read in all of the labels, together with names of images used
for i=1:numel(dataset_locs)
curr_labels = dir([dataset_locs{i} '\*.pts']);
imgs = dir([dataset_locs{i} '\*.jpg']);
if(isempty(imgs))
imgs = dir([dataset_locs{i} '\*.png']);
end
for p=1:numel(curr_labels)
landmarks = dlmread([dataset_locs{i}, curr_labels(p).name], ' ', [3,0,68+2,1]);
landmark_labels = cat(3, landmark_labels, landmarks);
img_locations = cat(1, img_locations, [dataset_locs{i} imgs(p).name]);
end
end
% go through all images, see which centres they match and then add to
% the appropriate bin
num_imgs = size(landmark_labels,3);
scales = zeros(num_imgs, 1);
views = zeros(num_imgs, 1);
for lbl=1:num_imgs
Msm = M;
Vsm = V;
labels = landmark_labels(:,:,lbl);
% Find the best PDM parameters given the 2D labels
[ a, R] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
eul = Rot2Euler(R);
eul = eul * 180 / pi;
% find the closest view
[~, view] = min(sum(abs(centres_all - repmat(eul, num_centers, 1)),2));
counter_colour(view) = counter_colour(view) + 1;
scales(lbl) = a;
views(lbl) = view;
end
% preallocate data
allExamplesColourAllViews = cell(size(centres_all,1),1);
landmarkLocationsAllViews = cell(size(centres_all,1),1);
for r=1:size(centres_all,1)
allExamplesColourAllViews{r} = uint8(zeros(counter_colour(r), imgSize(1), imgSize(2)));
landmarkLocationsAllViews{r} = zeros(counter_colour(r), num_landmarks, 2);
actual_imgs_used_all_views{r} = cell(counter_colour(r), 1);
end
counter_colour = zeros(num_centers,1);
% The shape fitting is performed in the reference frame of the
% patch training scale
refGlobal = [training_scale, 0, 0, 0, 0, 0]';
% go through all images and add to corresponding container
for lbl=1:num_imgs
% shift the pixels to be centered on pixel as opposed to top left
labels = landmark_labels(:,:,lbl) - 0.5;
imgCol = imread(img_locations{lbl});
if(size(imgCol,3) == 3)
imgCol = rgb2gray(imgCol);
end
% the reference shape
[ ~, ~, ~,~, local_params] = fit_PDM_ortho_proj_to_2D( Msm, E, Vsm, labels);
refShape = GetShapeOrtho(M, Vsm, local_params, refGlobal);
% Create transform using a slightly modified version of Kabsch that
% takes scaling into account as well, in essence we get a
% similarity transform from current estimate to reference shape
[A_img2ref, T_img2ref, ~, ~] = AlignShapesWithScale(labels, refShape(:,1:2));
T_img2ref = T_img2ref + [imgSize(1)/2, imgSize(2)/2];
% Create a transform, from shape in image to reference shape
T = affine2d([A_img2ref';T_img2ref]);
% transform the current shape to the reference one
shape2D_in_ref = bsxfun(@plus, (A_img2ref * labels')', T_img2ref);
% warp the image
[warped_img] = imwarp(imgCol, T, 'linear', 'OutputView', imref2d(imgSize));
counter_colour(views(lbl)) = counter_colour(views(lbl)) + 1;
allExamplesColourAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = warped_img;
landmarkLocationsAllViews{views(lbl)}(counter_colour(views(lbl)),:,:) = shape2D_in_ref;
actual_imgs_used_all_views{views(lbl)}{counter_colour(views(lbl))} = img_locations{lbl};
if(mod(lbl, 100) == 0)
fprintf('%d/%d done\n', lbl, num_imgs);
end
end
% write out the training data for each view
for r=1:size(centres_all,1)
mirrorIdx = find(sum(abs(centres_all - repmat([centres_all(r,1), -centres_all(r,2), -centres_all(r,3)], size(centres_all,1),1)),2)==0);
% if the mirrored view already added no need to do it again
% so if (0,-20,0) is done no need to compute (0,20,0)
if(mirrorIdx < r)
continue
end
mirrorImgs = allExamplesColourAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
mirrorLbls = landmarkLocationsAllViews{mirrorIdx}(1:counter_colour(mirrorIdx),:,:);
for i=1:size(mirrorImgs,1)
flippedImg = fliplr(squeeze(mirrorImgs(i,:,:)));
flippedLbls = squeeze(mirrorLbls(i,:,:));
flippedLbls(:,1) = imgSize(1) - flippedLbls(:,1) + 1;
tmp1 = flippedLbls(mirror_inds(:,1),:);
tmp2 = flippedLbls(mirror_inds(:,2),:);
flippedLbls(mirror_inds(:,2),:) = tmp1;
flippedLbls(mirror_inds(:,1),:) = tmp2;
mirrorImgs(i,:,:) = flippedImg;
mirrorLbls(i,:,:) = flippedLbls;
end
all_images = cat(1, allExamplesColourAllViews{r}(1:counter_colour(r),:,:), mirrorImgs);
landmark_locations = cat(1, landmarkLocationsAllViews{r}(1:counter_colour(r),:,:), mirrorLbls);
actual_imgs_used = actual_imgs_used_all_views{r};
actual_imgs_used = cat(1, actual_imgs_used_all_views{r}, actual_imgs_used_all_views{mirrorIdx});
centres = centres_all(r,:);
visiIndex = ones(1,68);
save([output_location '_' num2str(r) '.mat'], 'all_images', 'landmark_locations', 'training_scale', 'centres', 'actual_imgs_used', 'visiIndex', '-v7.3');
end
end

View File

@@ -0,0 +1,13 @@
This code is in support of the "Constrained Local Neural Fields for robust facial landmark detection in the wild" paper by Tadas Baltrusaitis, Peter Robinson, and Louis-Philippe Morency.
This code provides the code for training the patch experts used in the experiments reported in the paper.
You have to have the relevant datasets, to run the code, the in-the-wild datasets can be found at http://ibug.doc.ic.ac.uk/resources/facial-point-annotations/), the annotations are provided. The Multi-PIE dataset can be acquired from - http://www.multipie.org/, you will need to ask the authors of the dataset for the annotations.
./data_preparation/ folder contains scripts to prepare data for CCNF (CLNF) and SVR patch expert training
./ccnf_training/ and ./svr_training/ folders contain the training code itself.
I suggest starting with dataset preparation then with SVR and CCNF patch expert training.
The trained patch experts can then be used with the Matlab and C++ OpenFace landmark detection algorithms

View File

@@ -0,0 +1,35 @@
function [ patch_expert ] = CreateLogisticRegressor( samples, labels, w, b, normalisation_options)
%CREATELOGISTICREGRESSOR Given positive and negative example patches, and
%an SVR regressor that will be applied to them train a logistic regressor
%that will predict patch probabilities
% Can either use cross-correlation for applying the regressor or
% normalised cross-correlation
% Returns a patch expert which is [scaling, bias, support vectors)
% p(x) = 1/(1+exp(-(scaling * svmDecBound + bias)))
% before applying the SVR, patch expert weights are normalised
%(as they will be applied using normalised cross-correlation in the end)
meanTmp = mean(w);
w = w - meanTmp;
if(normalisation_options.useNormalisedCrossCorr)
eTmp = sqrt(sum((w - meanTmp).^2));
w = w / eTmp;
end
% can now apply the SVR regressor on the training data
svr_response = (w' * samples')';
% Learn a logistic regressor
[bLogit,dev,stats] = glmfit(svr_response, labels,'binomial','link','logit');
scaling = bLogit(2);
bias = bLogit(1);
support = w;
% Combine all the parameters into a patch expert
patch_expert = [scaling; bias; support]';
end

View File

@@ -0,0 +1,53 @@
function [ patch_expert, corr, rms_error] = CreatePatchExpert( samples, labels, unnormed_samples, normalisation_options)
%CREATEPATCHEXPERT Summary of this function goes here
% Detailed explanation goes here
num_examples = size(samples, 1);
region_length = normalisation_options.normalisationRegion - normalisation_options.patchSize + 1;
region_length = region_length(1) * region_length(2);
% this part sets the split boundaries for SVR training, logit training and test subsets
train_SVR_start = 1;
train_SVR_end = int32(normalisation_options.svmRatio * num_examples - 1);
train_SVR_end = train_SVR_end - mod(train_SVR_end, region_length);
train_logit_start = train_SVR_end + 1;
train_logit_end = train_logit_start + int32(normalisation_options.logitRatio * num_examples) - 1;
% make sure it ends within same area of interest (region)
train_logit_end = train_logit_end - mod(train_logit_end, region_length);
test_start = train_logit_end + 1;
test_end = size(samples,1);
% picking training data for SVR
examples_train_SVR = samples(train_SVR_start:train_SVR_end, :);
labels_train_SVR = labels(train_SVR_start:train_SVR_end);
% Train the SVR using liblinear (older version used libSVM,
% but liblinear is much faster)
[w, b] = Train_SVR(examples_train_SVR, labels_train_SVR);
% Now create the test dataset
examples_test = samples(test_start:test_end, :);
labels_test = labels(test_start:test_end);
% Training the logistic regressor now
examples_train_logit = samples(train_logit_start:train_logit_end, :);
labels_train_logit = labels(train_logit_start:train_logit_end, :);
patch_expert = CreateLogisticRegressor(examples_train_logit, labels_train_logit, w, b, normalisation_options);
% Evaluate the patch expert now
[rms_error, corr, ~] = EvaluatePatchExpert(examples_test, labels_test, patch_expert, false);
fprintf('Rms error %.3f, correlation %.3f\n', rms_error, corr);
% Assert that our implementation and the convolution based one are equivalent
[~, ~, responses_svm] = EvaluatePatchExpert(samples(1:size(unnormed_samples,1)*region_length,:), labels(1:size(unnormed_samples,1)*region_length), patch_expert, false);
[responses_ncc] = SVR_expert_ncc_response(unnormed_samples, patch_expert, normalisation_options, normalisation_options.normalisationRegion, region_length);
assert(mean(abs(responses_svm-responses_ncc))< 1e-2);
end

View File

@@ -0,0 +1,83 @@
function [ rmse, correlation, responses ] = EvaluatePatchExpert( samples, labels, patch_expert, vis)
%EVALUATEPATCHEXPERT Summary of this function goes here
% Detailed explanation goes here
if(vis)
% randomise for display purposes (otherwise samples from same
% region are next to each other)
r = randperm(size(samples,1));
samples = samples(r,:);
labels = labels(r,:);
end
w = patch_expert(3:end);
% calculate the response
svr_response = (w * samples')';
% Now that we have the response can compute logit regressor responses
scaling = patch_expert(1);
bias = patch_expert(2);
responses = (1 + exp(- (svr_response*scaling + bias))).^-1;
rmse = sqrt(mean((responses - labels).^2));
correlation = corr(responses, labels)^2;
% these are very add hoc
falseNegative = (responses < 0.2) & labels > 0.8;
falsePositive = (responses > 0.4) & labels < 0.2;
trueNegative = (responses < 0.1) & labels < 0.1;
truePositive = (responses > 0.3) & labels > 0.6;
% Visualising the responses
if(vis)
subplot(2,2,1)
maxFN = min([sum(falseNegative),100]);
if(maxFN > 0)
[ false_negatives ] = generateDisplayData( samples(find(falseNegative, maxFN),:));
imagesc(false_negatives);
colormap(gray)
title('false negatives')
else
imagesc([0]);
end
subplot(2,2,2)
maxFP = min([sum(falsePositive),100]);
if(maxFP > 0)
[ false_positives ] = generateDisplayData( samples(find(falsePositive,maxFP),:));
imagesc(false_positives);
colormap(gray)
title('false positives')
else
imshow([0]);
end
subplot(2,2,3)
maxTP = min([sum(truePositive),100]);
if(maxTP > 0)
[ true_positives ] = generateDisplayData( samples(find(truePositive,maxTP),:));
imagesc(true_positives);
colormap(gray)
title('true positives')
else
imagesc([0]);
end
subplot(2,2,4)
maxTN = min([sum(trueNegative),100]);
if(maxTN > 0)
[ true_negatives ] = generateDisplayData( samples(find(trueNegative,maxTN),:));
imagesc(true_negatives);
colormap(gray)
title('true negatives')
else
imshow([0]);
end
drawnow expose
end
end

View File

@@ -0,0 +1,140 @@
function [samples, labels, samples_unnormed] = ExtractTrainingSamples(examples, landmarkLoc, sigma, evaluation_size, patch_expert_support_size, numSamples, landmark, normalisation_options)
%%
% for an area of interest of 19x19 and patch support region of 11x11, we
% would have 9x9=81 samples (9 is the single_input_size, 11 is
% patch_expert_support_size, 19x19 is normalisation_size, 9 would be the
% normalisation_side_size)
normalisation_side_size = (evaluation_size - 1)/2;
single_input_size = evaluation_size - patch_expert_support_size + 1;
% Determine the ratio of images to be sampled (most likely not all of them will be)
samples_per_img = (numSamples / (size(examples,1) * (1 + normalisation_options.rate_negative))) / (single_input_size(1)^2);
num_samples = int32(samples_per_img * (1 + normalisation_options.rate_negative) * size(examples,1) * (single_input_size(1)^2));
%% Initialise the samples and labels
samples = zeros(num_samples, patch_expert_support_size(1) * patch_expert_support_size(2));
labels = zeros(num_samples, 1);
%% Initialise the unnormed versions of the images
% This is done in order to assert our use of algorithms for calculating
% the responses, as for training we might use regular ml procedures,
% whereas for fitting normalised cross-correlation or just
% cross-correlation will be used, so keep some unnormed samples
samples_unnormed = zeros(int32(num_samples/300), evaluation_size(1)^2);
img_size = [size(examples,2), size(examples,3)];
% making sure randomisation starts at the same point
rng(0);
% Pick the images to use
samples_to_use = randperm(size(examples,1));
% either use all of the images or part of them
if(samples_per_img*size(examples,1) > size(examples,1))
samples_to_use = 1:size(examples,1);
else
samples_to_use = samples_to_use(1:round(samples_per_img*size(examples,1)));
end
% Keep track of how many samples have been computed already
samples_filled = 1;
samples_unnormed_filled = 1;
v = [1];
h = [-1 0 1];
for i=samples_to_use
% Do rate_negative negatives and a single positive
for p=1:normalisation_options.rate_negative+1
% create a gaussian
corrPoint = landmarkLoc(i,landmark,:);
% Ignore occluded points
if(corrPoint(1) == 0)
break;
end
startX = 1 - corrPoint(1);
startY = 1 - corrPoint(2);
patchWidth = img_size(2);
patchHeight = img_size(1);
[X, Y] = meshgrid(startX:patchWidth + startX-1, startY:patchHeight + startY-1);
response = exp(-0.5*(X.^2+Y.^2)/(sigma^2));
% Choose positive or negative sample
if(p==normalisation_options.rate_negative+1)
sample_centre = squeeze(corrPoint) + round(1*randn(2,1));
else
sample_centre = squeeze(corrPoint) + round(10*randn(2,1));
end
sample_centre = round(sample_centre);
sample_centre(sample_centre <= normalisation_side_size(1)) = normalisation_side_size(1) + 1;
sample_centre(sample_centre > img_size(1)-normalisation_side_size(1)) = img_size(1) - normalisation_side_size(1) - 1;
patches = squeeze(examples(i, sample_centre(2) - normalisation_side_size:sample_centre(2) + normalisation_side_size, sample_centre(1) - normalisation_side_size:sample_centre(1) + normalisation_side_size));
if(samples_unnormed_filled <= size(samples_unnormed,1))
% even if correct size is not initialised Matlab will
% sort that out (would only happen once anyway)
samples_unnormed(samples_unnormed_filled,:) = patches(:);
samples_unnormed_filled = samples_unnormed_filled + 1;
end
if(strcmp(normalisation_options.patch_type, 'grad'))
edgeX = conv2(conv2(double(patches), v, 'same'), h, 'same');
edgeY = conv2(conv2(double(patches), v', 'same'), h', 'same');
patches = edgeX.^2 + edgeY.^2;
end
side = (single_input_size - 1)/2;
responses = response(sample_centre(2) - side(2):sample_centre(2) + side(2), sample_centre(1) - side(1):sample_centre(1) + side(1));
% if we want to normalise each patch individualy do it here
patch = im2col(patches, patch_expert_support_size, 'sliding')';
response = im2col(responses, [1,1], 'sliding');
labels(samples_filled:samples_filled+size(patch,1)-1,:) = response;
samples(samples_filled:samples_filled+size(patch,1)-1,:) = patch;
samples_filled = samples_filled + size(patch,1);
end
end
if(normalisation_options.useNormalisedCrossCorr == 1)
mean_curr = mean(samples, 2);
patch_normed = samples - repmat(mean_curr,1, patch_expert_support_size(1)*patch_expert_support_size(2));
% Normalising the patches using the L2 norm
scaling = sqrt(sum(patch_normed.^2,2));
scaling(scaling == 0) = 1;
patch_normed = patch_normed ./ repmat(scaling, 1, patch_expert_support_size(1)*patch_expert_support_size(2));
samples = patch_normed;
end
% Only keep the filled samples
samples = samples(1:samples_filled-1,:);
labels = labels(1:samples_filled-1,:);
if((samples_filled-1)/(single_input_size(1)*single_input_size(2)) < size(samples_unnormed,1))
samples_unnormed = samples_unnormed(1:(samples_filled-1)/(single_input_size(1)*single_input_size(2)),:);
end
end

View File

@@ -0,0 +1,42 @@
function [ normalisation_options ] = Parse_settings( sigma, patch_type, ratio_neg, num_samples, varargin)
%PARSE_SETTINGS Summary of this function goes here
% Detailed explanation goes here
% creating the parameters to use when training colour (intensity) patches
normalisation_options = struct;
% this is what currently is expected (although could potentially have
% bigger or smaller support regions
normalisation_options.patchSize = [11 11];
% The region size of a region that is taken for training around an
% aligned or misaligned landmark
if(sum(strcmp(varargin,'normalisation_size')))
ind = find(strcmp(varargin,'normalisation_size')) + 1;
normalisation_options.normalisationRegion = [varargin{ind}, varargin{ind}];
else
normalisation_options.normalisationRegion = [21 21];
end
% This specifies the split of data ratios
normalisation_options.svmRatio = 0.8; % proportion of data used for training SVR
normalisation_options.logitRatio = 0.1; % proportion of data for training logistic regressors
% the rest is used for testing and provides the correlation and rms scores
% should normalised cross correlation or just cross correlation should
% be used on the patch as an SVR
normalisation_options.useNormalisedCrossCorr = 1;
% the patch types to be used (for now 'reg' (raw pixel values), and
% 'grad' (gradient intensity values)
normalisation_options.patch_type = patch_type;
% number of training samples to use
normalisation_options.numSamples = num_samples;
normalisation_options.sigma = sigma;
normalisation_options.rate_negative = ratio_neg;
end

View File

@@ -0,0 +1,59 @@
function [ responses ] = SVR_expert_ncc_response( patches, patch_experts, normalisation_options, window_size, patch_length)
%PATCHRESPONSESVM Summary of this function goes here
% Detailed explanation goes here
% reshape the separate patches into proper images
patchSize = normalisation_options.patchSize;
responses = zeros(size(patches,1), (window_size(1)-patchSize(1)+1)^2);
% prepare the patches through either turning them to gradients or
% if(normalisation_options.useNormalisedCrossCorr)
% patches = zscore(patches);
% end
w = reshape(patch_experts(3:end), patchSize);
v = [1];
h = [-1 0 1];
for i = 1:size(patches,1)
colNorm = normalisation_options.useNormalisedCrossCorr == 1;
smallRegionVec = patches(i,:);
smallRegion = reshape(smallRegionVec, window_size(1), window_size(2));
if(strcmp(normalisation_options.patch_type, 'grad'))
edgeX = conv2(conv2(smallRegion, v, 'same'), h, 'same');
edgeY = conv2(conv2(smallRegion, v', 'same'), h', 'same');
smallRegion = edgeX.^2 + edgeY.^2;
end
response = SVMresponse(smallRegion, w, colNorm, patchSize);
response = (exp(-(patch_experts(1)*response+patch_experts(2)))+1).^-1;
responses(i,:) = response(:);
end
responses = responses';
responses = responses(:);
end
function response = SVMresponse(region, patchExpert, normalise_x_corr,patchSize)
if(normalise_x_corr)
[response] = normxcorr2(patchExpert, region);
% the much faster mex version
% [response] = normxcorr2_mex(patchExpert, region);
response = response(patchSize(1):end-patchSize(1)+1,patchSize(2):end-patchSize(2)+1);
else
% this assumes that the patch is already normed, so just use
% cross-correlation
template = rot90(patchExpert,2);
response = conv2(region, template, 'valid');
end
end

View File

@@ -0,0 +1,38 @@
% This is the main script runner for training, it collects the
% training samples, followed by model training
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
scales = [0.25, 0.35, 0.5];
% the data generation parameters
sigma = 1;
num_samples = 5e5;
ratio_neg = 5;
norm = 1;
normalisation_size = 19;
patch_types = {'reg', 'grad'};
% Should a frontal view be created
frontalView = [1];
% The other views to be used
profileViewInds = [];
upDownViewInds = [];
version = 'cofw';
% the naming of
wild_loc = 'cofw_';
for s=scales
Train_all(root, frontalView, profileViewInds, upDownViewInds, s,...
sigma, version, norm, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', wild_loc,...
'patch_types', patch_types, 'normalisation_size', normalisation_size);
end

View File

@@ -0,0 +1,38 @@
% This is the main script runner for training, it collects the
% training samples, followed by model training
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
scales = [0.25, 0.35, 0.5];
% the data generation parameters
sigma = 1;
num_samples = 1e6;
ratio_neg = 10;
norm = 1;
normalisation_size = 19;
patch_types = {'reg', 'grad'};
% Should a frontal view be created
frontalView = [1];
% The other views to be used
profileViewInds = [2,3,4];
upDownViewInds = [];
version = 'general';
% the naming of
wild_loc = 'combined_';
for s=scales
Train_all(root, frontalView, profileViewInds, upDownViewInds, s,...
sigma, version, norm, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', wild_loc,...
'patch_types', patch_types, 'normalisation_size', normalisation_size);
end

View File

@@ -0,0 +1,38 @@
% This is the main script runner for training, it collects the
% training samples, followed by model training
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
scales = [0.25, 0.35, 0.5];
% the data generation parameters
sigma = 1;
num_samples = 5e5;
ratio_neg = 5;
norm = 1;
normalisation_size = 19;
patch_types = {'reg', 'grad'};
% Should a frontal view be created
frontalView = [1];
% The other views to be used
profileViewInds = [2,3,4];
upDownViewInds = [];
version = 'multi_pie';
% the naming of
wild_loc = 'mpie_';
for s=scales
Train_all(root, frontalView, profileViewInds, upDownViewInds, s,...
sigma, version, norm, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', wild_loc,...
'patch_types', patch_types, 'normalisation_size', normalisation_size);
end

View File

@@ -0,0 +1,38 @@
% This is the main script runner for training, it collects the
% training samples, followed by model training
clear
% define the root name of database
root = '../data_preparation/prepared_data/';
% which scales we're doing
scales = [0.25, 0.35, 0.5];
% the data generation parameters
sigma = 1;
num_samples = 5e5;
ratio_neg = 5;
norm = 1;
normalisation_size = 19;
patch_types = {'reg', 'grad'};
% Should a frontal view be created
frontalView = [1];
% The other views to be used
profileViewInds = [2];
upDownViewInds = [];
version = 'wild';
% the naming of
wild_loc = 'wild_';
for s=scales
Train_all(root, frontalView, profileViewInds, upDownViewInds, s,...
sigma, version, norm, 'ratio_neg', ratio_neg,...
'num_samples', num_samples, 'data_loc', wild_loc,...
'patch_types', patch_types, 'normalisation_size', normalisation_size);
end

View File

@@ -0,0 +1,91 @@
function [correlations, rms_errors, patch_experts, visi_index, centres, normalisation_options] ...
= TrainPatchExperts(trainingLoc, view, scale, sigma, patch_type, ratio_neg, num_samples, varargin)
% Training patch experts for all of the landmarks for a particular view
% and scale
% Get the training parameters
normalisation_options = Parse_settings( sigma, patch_type, ratio_neg, num_samples, varargin{:});
% Load the training data
if(sum(strcmp(varargin,'data_loc')))
ind = find(strcmp(varargin,'data_loc')) + 1;
data_loc = varargin{ind};
data_loc = sprintf(['%s/' data_loc '%s_%s.mat'], trainingLoc, num2str(scale), num2str(view));
else
data_loc = sprintf('%s/wild_%s_%s.mat', trainingLoc, num2str(scale), num2str(view));
end
load(data_loc);
examples = all_images;
visi_index = visiIndex;
clear 'all_images'
numPoints = size(landmark_locations,2);
correlations = zeros(1, numPoints);
rms_errors = zeros(1, numPoints);
patch_experts = zeros(1, numPoints, normalisation_options.patchSize(1)*normalisation_options.patchSize(2)+2);
for j=1:numPoints
% can only do mirroring if there is no yaw
if((numPoints == 68 || numPoints == 29 )&& centres(2) == 0)
% Do not redo a mirror feature (just flip them)
if(numPoints == 68)
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,65;62,64;68,66];
else
mirrorInds = [1,2; 3,4; 5,7; 6,8; 9,10; 11,12; 13,15; 14,16; 17,18; 19,20; 23,24];
end
mirror_idx = j;
if(any(mirrorInds(:,1)==j))
mirror_idx = mirrorInds(mirrorInds(:,1)==j,2);
elseif(any(mirrorInds(:,2)==j))
mirror_idx = mirrorInds(mirrorInds(:,2)==j,1);
end
if(mirror_idx~=j & correlations(1,mirror_idx) ~= 0)
correlations(1,j) = correlations(1,mirror_idx);
rms_errors(1, j) = rms_errors(1,mirror_idx);
% Bias and scaling are the same
patch_experts(1, j, 1:2) = patch_experts(1, mirror_idx, 1:2);
% flip the support weights
w = patch_experts(1, mirror_idx, 3:end);
w = reshape(w, normalisation_options.patchSize(1), normalisation_options.patchSize(2));
w = fliplr(w);
w = reshape(w, normalisation_options.patchSize(1)*normalisation_options.patchSize(2),1);
patch_experts(1, j, 3:end) = w;
fprintf('Feature %d done\n', j);
continue;
end
end
if(visi_index(j))
% instead of loading the patches compute them here:
numSamples = normalisation_options.numSamples;
[curr_examples, currentLabels, unnormed_samples] = ExtractTrainingSamples(examples, landmark_locations, sigma, normalisation_options.normalisationRegion, normalisation_options.patchSize, numSamples, j, normalisation_options);
[ patchExpert, correlation, rmsError ] = CreatePatchExpert( curr_examples, currentLabels, unnormed_samples, normalisation_options);
correlations(1,j) = correlation;
rms_errors(1, j) = rmsError;
patch_experts(1, j, :) = patchExpert(:);
fprintf('Feature %d done\n', j);
end
end
end

View File

@@ -0,0 +1,18 @@
function [w, b] = Train_SVR(samples, labels)
%Train_SVR creating a linear support vector regressor
% liblinear training
addpath('C:\liblinear\matlab');
% Remove redundant data
[samples, inds] = unique(samples, 'rows');
labels = labels(inds,:);
cmd = ['-s 11 -B 1 -q'];
svr_regressor = train(labels, sparse(double(samples)), cmd);
w = svr_regressor.w(1:end-1)';
b = svr_regressor.w(end);
end

View File

@@ -0,0 +1,167 @@
function Train_all(trainingLoc, frontalView, profile_views, up_down_views, scaling, sigma, version, varargin)
%% Set up some default values if not defined
if(sum(strcmp(varargin,'ratio_neg')))
ind = find(strcmp(varargin,'ratio_neg')) + 1;
ratio_neg = varargin{ind};
else
ratio_neg = 20;
end
if(sum(strcmp(varargin,'num_samples')))
ind = find(strcmp(varargin,'num_samples')) + 1;
num_samples = varargin{ind};
else
num_samples = 5e5;
end
if(sum(strcmp(varargin,'patch_types')))
ind = find(strcmp(varargin,'patch_types')) + 1;
patch_types = varargin{ind};
else
patch_types = {'reg', 'grad'};
end
if(any(strcmp(varargin,'mirror_view_inds')))
ind = find(strcmp(varargin,'mirror_view_inds')) + 1;
mirror_view_inds = varargin{ind};
else
mirror_view_inds = [];
end
patches_m = struct;
patches_m.types = patch_types;
patches_m.correlations = cell(numel(patch_types), 1);
patches_m.rms_errors = cell(numel(patch_types), 1);
patches_m.patch_experts = cell(numel(patch_types), 1);
% first do the frontal view
[visiIndex, centres, patches_m, norm_options] = ...
AppendTraining(trainingLoc, frontalView, scaling, sigma, [], [], patches_m, ratio_neg, num_samples, varargin{:});
fprintf('Frontal done\n');
% The mirrored views
for i=1:numel(mirror_view_inds)
[visiIndex, centres, patches_m] = ...
AppendTraining(trainingLoc, mirror_view_inds(i), scaling, sigma, visiIndex, centres, patches_m, ratio_neg, num_samples, varargin{:}, 'mirror');
fprintf('Mirrored view %d done\n', i);
end
% now do the profile views
for i=1:numel(profile_views)
[visiIndex, centres, patches_m] = ...
AppendTraining(trainingLoc, profile_views(i), scaling, sigma, visiIndex, centres, patches_m, ratio_neg, num_samples, varargin{:});
fprintf('Profile %d done\n', i);
end
% saving time by not retraining mirrored (left/right) views, but just
% filpping the patch expert
for i=1:numel(profile_views)
[visiIndex, centres, patches_m] = ...
AppendMirror(visiIndex, centres, patches_m, numel(profile_views) - i + 2, varargin{:});
fprintf('Profile %d done\n', i + numel(profile_views));
end
% The up/down views
for i=1:numel(up_down_views)
[visiIndex, centres, patches_m] = ...
AppendTraining(trainingLoc, up_down_views(i), scaling, sigma, visiIndex, centres, patches_m, ratio_neg, num_samples, varargin{:});
fprintf('Up down view %d done\n', i);
end
patches_m.patch_expert_type = 'SVR';
% output the training
locationTxtCol = sprintf('trained/svr_patches_%s_%s.txt', num2str(scaling), version);
locationMlabCol = sprintf('trained/svr_patches_%s_%s.mat', num2str(scaling), version);
Write_patch_experts_multi_modal(locationTxtCol, locationMlabCol, scaling, centres, visiIndex, patches_m, norm_options);
end
function [visi_index, centres, patches_m, norm_options] = AppendTraining(training_data_loc, view, scale, sigma, visibilities_init, centres_init, patches_m_init, ratio_neg, num_samples, varargin)
patches_m = patches_m_init;
for i=1:numel(patches_m.types)
[correlations, rms_errors, patch_experts, visi_index, centres, norm_options] = TrainPatchExperts(training_data_loc, view, scale, sigma, patches_m.types{i}, ratio_neg, num_samples, varargin{:});
if(numel(patches_m_init.correlations{i}) > 0)
patches_m.correlations{i} = cat(1, patches_m_init.correlations{i}, correlations);
patches_m.rms_errors{i} = cat(1, patches_m_init.rms_errors{i}, rms_errors);
patches_m.patch_experts{i} = cat(1, patches_m_init.patch_experts{i}, patch_experts);
else
patches_m.correlations{i} = correlations;
patches_m.rms_errors{i} = rms_errors;
patches_m.patch_experts{i} = patch_experts;
end
end
% also add the visibility indices and centres, as that will need to be
% output to the patch expert when it's written out
if(numel(visibilities_init) > 0)
visi_index = cat(1, visibilities_init, visi_index);
centres = cat(1, centres_init, centres);
end
end
function [visiIndex, centres, patches_m] = AppendMirror(visiIndexInit, centresInit, patches_m, index, varargin)
% this specifies the mirrored points, say 1 in left profile becomes 17
% in right profile if mirrored, non-mirrored points don't need to be
% specified, they just get flipped but index remains the same
mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
61,63;66,64];
if(numel(visiIndexInit) > 0)
for i=1:numel(patches_m.types)
corr_T = patches_m.correlations{i}(index,:);
corr_T = swap(corr_T, mirrorInds(:,1), mirrorInds(:,2));
patches_m.correlations{i} = cat(1, patches_m.correlations{i}, corr_T);
AccT = patches_m.rms_errors{i}(index,:);
AccT = swap(AccT, mirrorInds(:,1), mirrorInds(:,2));
patches_m.rms_errors{i} = cat(1, patches_m.rms_errors{i}, AccT);
patchExpertMirror = patches_m.patch_experts{i}(index,:,:);
patchExpertMirrorT1 = patchExpertMirror(1,mirrorInds(:,1),:);
patchExpertMirrorT2 = patchExpertMirror(1,mirrorInds(:,2),:);
patchExpertMirror(1,mirrorInds(:,2),:) = patchExpertMirrorT1;
patchExpertMirror(1,mirrorInds(:,1),:) = patchExpertMirrorT2;
% To flip a patch expert it
for p=1:size(patchExpertMirror,2)
patchExpertMirror(1,p,3:end) = reshape(fliplr(reshape(patchExpertMirror(1,p,3:end),11,11)),121,1);
end
patches_m.patch_experts{i} = cat(1, patches_m.patch_experts{i}, patchExpertMirror);
end
visiIndexT = visiIndexInit(index,:);
visiIndexT = swap(visiIndexT, mirrorInds(:,1), mirrorInds(:,2));
visiIndex = cat(1, visiIndexInit, visiIndexT);
% mirroring of the orientation involves flipping yaw or roll (we
% assume only views with one rotation will be present (say only
% pitch or yaw or roll)
centresMirror = [centresInit(index,1), -centresInit(index,2), -centresInit(index,3)];
centres = cat(1, centresInit, centresMirror);
end
end
function arr = swap(arr, ind1, ind2)
val1 = arr(ind1);
val2 = arr(ind2);
arr(ind1) = val2;
arr(ind2) = val1;
end

View File

@@ -0,0 +1,62 @@
function Write_patch_experts_multi_modal(locationTxt, locationMlab, trainingScale, centers, visiIndex, patch_experts, normalisationOptions)
patches_file = fopen(locationTxt, 'w');
[views, landmarks, ~] = size(patch_experts.patch_experts{1});
fprintf(patches_file, '# scaling factor of training\r\n%f\r\n', trainingScale);
% write out the scaling factor as this is what will be used when
% fitting on the window
fprintf(patches_file, '# number of views\r\n%d\r\n', views);
% Write out the information about the view's and centers here
fprintf(patches_file, '# centers of the views\r\n');
for i=1:views
% this indicates that we're writing a 3x1 double matrix
writeMatrix(patches_file, centers(i,:)', 6);
end
fprintf(patches_file, '# visibility indices per view\r\n');
for i=1:views
% this indicates that we're writing a 3x1 double matrix
writeMatrix(patches_file, visiIndex(i,:)', 4);
end
fprintf(patches_file, '# Patches themselves (1 line patches of a vertex)\r\n');
for i=1:views
for j=1:landmarks
num_patches = size(patch_experts.patch_experts, 1);
% MPatch(3), width, height, nPatches(1 or 0), Patch(2), type(0),
% scaling(1) bias, rows, cols, type
fprintf(patches_file, '%d %d %d %d ', 3, 11, 11, num_patches);
for k=1:num_patches
if(strcmp(patch_experts.types{k}, 'reg'))
type = 0;
elseif(strcmp(patch_experts.types{k}, 'grad'))
type = 1;
else
fprintf('Not supported patch type\n');
type = 0;
end
% also add patch confidence based on correlation scores
fprintf(patches_file, '%d %d %f %f %f %d %d %d ', 2, type, patch_experts.correlations{k}(i,j), patch_experts.patch_experts{k}(i,j,1), patch_experts.patch_experts{k}(i,j,2), 11, 11, 5);
fprintf(patches_file, '%f ', patch_experts.patch_experts{k}(i,j,3:end));
fprintf(patches_file,'\r\n');
end
% the actual matrix and gain
end
end
fclose(patches_file);
save(locationMlab, 'patch_experts', 'trainingScale', 'centers', 'visiIndex', 'normalisationOptions');
end

View File

@@ -0,0 +1,56 @@
function [ display_array ] = generateDisplayData( X )
%GENERATEDISPLAYDATA Summary of this function goes here
% Detailed explanation goes here
example_width = 11;
example_height = 11;
% Compute rows, cols
[m n] = size(X);
% Compute number of items to display
display_rows = floor(sqrt(m));
display_cols = ceil(m / display_rows);
% Between images padding
pad = 1;
% Setup blank display
display_array = double(zeros(pad + display_rows * (example_height + pad), ...
pad + display_cols * (example_width + pad)));
% Copy each example into a patch on the display array
curr_ex = 1;
for j = 1:display_rows
for i = 1:display_cols
if curr_ex > m,
break;
end
% Copy the patch
% if(isa(X, 'uint8'))
display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...
pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...
reshape(X(curr_ex, :), example_height, example_width);
% else
% % Get the max value of the patch
% minVal = min(X(curr_ex, X(curr_ex,:)~=0)) - 10;
% if(numel(minVal) < 1)
% minVal = 0;
% end
% maxVal = double(max(X(curr_ex,:)-minVal))/255.0;
% if(numel(minVal) < 1 || maxVal == 0)
% maxVal = 1;
% end
% display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...
% pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...
% reshape((X(curr_ex, :)-minVal)/maxVal, example_height, example_width);
% end
curr_ex = curr_ex + 1;
end
if curr_ex > m,
break;
end
end
end

View File

@@ -0,0 +1,8 @@
The script that will train the SVR patch experts is:
Script_Training_wild.m for the 300-W results
Script_Training_mpie.m for training on Multi-PIE data
Script_Training_general.m for combined dataset training
However, you will first need to generate the training data, found in ../data_preparation
The code also relies on you having a compiled liblinear library and have it in 'C:/liblinear/' folder, you can change the location where matlab looks for it in the Train_SVR.m script.

View File

@@ -0,0 +1,103 @@
# scaling factor of training
0.250000
# number of views
1
# centers of the views
3
1
6
0.000000000
0.000000000
0.000000000
# visibility indices per view
29
1
4
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
# Patches themselves (1 line patches of a vertex)
3 11 11 2 2 0 0.104844 10.819208 -4.484403 11 11 5 0.066570 0.013390 -0.004439 0.001292 0.013524 0.042933 0.025160 0.025641 0.022201 0.031750 0.070895 -0.096844 -0.005614 -0.000297 -0.008393 -0.045556 -0.044604 -0.022772 -0.001255 -0.035560 -0.028339 -0.090393 -0.082565 -0.016230 -0.038638 -0.017827 0.001124 -0.023380 -0.013918 0.025335 -0.009523 0.022481 -0.033379 -0.060681 -0.017600 -0.043102 -0.018157 0.000999 0.006393 0.009683 -0.013016 -0.012089 0.021374 -0.019956 -0.041925 -0.031789 -0.033840 -0.046090 0.005783 0.098152 0.045900 -0.040542 0.011516 0.027511 0.048071 -0.039766 -0.007868 -0.059894 -0.040721 0.140328 0.077937 -0.050552 -0.048031 0.050738 0.004403 0.161369 -0.001173 0.015852 0.001335 0.137095 0.066533 -0.241558 -0.140930 0.034414 0.121280 -0.062968 0.157144 0.013133 -0.026616 0.056425 0.148740 -0.104673 -0.275480 0.085421 0.159151 0.100892 -0.185044 0.103876 0.050676 0.047667 0.138973 0.084888 -0.112598 -0.090533 0.162830 0.001724 -0.143021 -0.332474 0.123276 -0.030579 0.031604 0.034923 -0.080244 -0.083511 -0.003523 0.159918 0.006613 -0.007804 -0.150022 0.118553 0.096008 0.140313 0.214384 0.070068 -0.086809 -0.074745 0.056791 -0.185867 -0.138597 -0.165999 0.156962
2 1 0.020013 5.162621 -3.971740 11 11 5 -0.136561 -0.039843 -0.066338 -0.017715 0.022926 -0.000165 0.001857 0.010458 -0.054978 0.024008 -0.053994 0.020310 0.046119 0.012275 0.048576 0.061547 0.068964 0.057014 0.026483 0.006710 0.018023 -0.065465 -0.118313 0.002068 0.005025 0.004576 -0.062310 -0.051380 0.034390 0.067753 -0.005822 0.014977 -0.060096 -0.057934 0.017852 -0.000013 0.021730 0.021452 -0.005047 0.019996 0.047683 0.003925 0.014129 0.014086 -0.035980 0.050064 0.052134 0.002402 -0.056546 -0.052899 -0.044456 -0.037770 -0.048897 -0.018546 -0.048721 0.040136 0.037264 0.045961 -0.070413 -0.077491 -0.065816 -0.004103 0.034850 -0.040167 0.000715 -0.016825 0.025131 0.012286 0.015957 -0.036154 0.033832 0.035742 0.060358 -0.038782 -0.085551 -0.029123 -0.065445 0.005395 -0.058192 -0.068522 0.055023 0.140714 0.069014 -0.049531 -0.062777 0.038771 0.134401 0.033692 -0.022782 -0.247817 -0.086441 0.128732 0.122917 -0.073948 -0.179714 -0.045818 0.122887 0.151508 -0.022765 -0.053239 -0.296049 0.039076 0.212077 0.115568 0.031569 0.002365 0.154818 0.220304 0.250460 0.046766 -0.170995 -0.407040 0.006551 0.208815 0.107720 -0.045877 -0.110612 0.009777 0.020632 0.184251 -0.103767
3 11 11 2 2 0 0.104844 10.819208 -4.484403 11 11 5 0.096008 0.140313 0.214384 0.070068 -0.086809 -0.074745 0.056791 -0.185867 -0.138597 -0.165999 0.156962 -0.030579 0.031604 0.034923 -0.080244 -0.083511 -0.003523 0.159918 0.006613 -0.007804 -0.150022 0.118553 0.050676 0.047667 0.138973 0.084888 -0.112598 -0.090533 0.162830 0.001724 -0.143021 -0.332474 0.123276 0.013133 -0.026616 0.056425 0.148740 -0.104673 -0.275480 0.085421 0.159151 0.100892 -0.185044 0.103876 -0.001173 0.015852 0.001335 0.137095 0.066533 -0.241558 -0.140930 0.034414 0.121280 -0.062968 0.157144 -0.039766 -0.007868 -0.059894 -0.040721 0.140328 0.077937 -0.050552 -0.048031 0.050738 0.004403 0.161369 -0.041925 -0.031789 -0.033840 -0.046090 0.005783 0.098152 0.045900 -0.040542 0.011516 0.027511 0.048071 -0.060681 -0.017600 -0.043102 -0.018157 0.000999 0.006393 0.009683 -0.013016 -0.012089 0.021374 -0.019956 -0.082565 -0.016230 -0.038638 -0.017827 0.001124 -0.023380 -0.013918 0.025335 -0.009523 0.022481 -0.033379 -0.096844 -0.005614 -0.000297 -0.008393 -0.045556 -0.044604 -0.022772 -0.001255 -0.035560 -0.028339 -0.090393 0.066570 0.013390 -0.004439 0.001292 0.013524 0.042933 0.025160 0.025641 0.022201 0.031750 0.070895
2 1 0.020013 5.162621 -3.971740 11 11 5 -0.170995 -0.407040 0.006551 0.208815 0.107720 -0.045877 -0.110612 0.009777 0.020632 0.184251 -0.103767 -0.053239 -0.296049 0.039076 0.212077 0.115568 0.031569 0.002365 0.154818 0.220304 0.250460 0.046766 -0.022782 -0.247817 -0.086441 0.128732 0.122917 -0.073948 -0.179714 -0.045818 0.122887 0.151508 -0.022765 0.005395 -0.058192 -0.068522 0.055023 0.140714 0.069014 -0.049531 -0.062777 0.038771 0.134401 0.033692 0.025131 0.012286 0.015957 -0.036154 0.033832 0.035742 0.060358 -0.038782 -0.085551 -0.029123 -0.065445 0.040136 0.037264 0.045961 -0.070413 -0.077491 -0.065816 -0.004103 0.034850 -0.040167 0.000715 -0.016825 -0.035980 0.050064 0.052134 0.002402 -0.056546 -0.052899 -0.044456 -0.037770 -0.048897 -0.018546 -0.048721 -0.057934 0.017852 -0.000013 0.021730 0.021452 -0.005047 0.019996 0.047683 0.003925 0.014129 0.014086 -0.118313 0.002068 0.005025 0.004576 -0.062310 -0.051380 0.034390 0.067753 -0.005822 0.014977 -0.060096 0.020310 0.046119 0.012275 0.048576 0.061547 0.068964 0.057014 0.026483 0.006710 0.018023 -0.065465 -0.136561 -0.039843 -0.066338 -0.017715 0.022926 -0.000165 0.001857 0.010458 -0.054978 0.024008 -0.053994
3 11 11 2 2 0 0.259110 13.591304 -5.680955 11 11 5 -0.027448 0.066125 0.027320 -0.057769 -0.066195 0.016498 0.061969 -0.093604 -0.062659 -0.162218 0.133017 -0.020220 0.073828 0.054584 0.026991 -0.051658 -0.036766 0.029945 -0.040521 -0.028652 -0.054207 0.005797 -0.005093 0.077494 0.090830 0.019572 -0.132621 -0.101163 -0.021018 -0.069853 -0.053513 -0.154831 0.069686 -0.007804 0.066182 0.121761 0.095763 -0.164570 -0.181157 -0.001176 -0.039541 0.024337 -0.068909 0.039717 -0.038708 0.067468 0.099958 0.153679 -0.142199 -0.268290 -0.033868 0.007266 0.038080 -0.069530 0.032380 -0.003448 0.047509 0.076519 0.173045 0.026979 -0.238807 -0.138952 -0.032227 0.010314 -0.044823 0.112087 0.004289 0.007529 0.044226 0.082261 0.194104 -0.005143 -0.114492 -0.124481 -0.072713 -0.065813 0.047719 -0.000918 -0.050712 0.009193 -0.022796 0.118685 0.138305 0.040946 -0.050214 -0.050302 -0.034739 -0.004664 0.006553 -0.048319 0.033570 0.009222 0.040333 0.072617 0.046326 -0.010144 -0.000205 -0.032410 0.001303 -0.020531 -0.062352 -0.000842 -0.030872 -0.024987 0.054250 0.133732 0.205709 0.256510 0.167498 0.286865 0.001019 -0.011840 0.098092 0.053590 0.000125 -0.049693 -0.111459 -0.089173 -0.075840 -0.142558 -0.079042
2 1 0.196996 8.793545 -4.730062 11 11 5 0.013831 -0.028865 0.028508 0.031279 -0.023129 0.014394 0.017833 0.020322 0.028058 0.045902 -0.028352 -0.045532 -0.136490 -0.001702 0.113738 0.092326 0.015315 0.024025 0.046474 0.064100 0.099514 0.020830 -0.034048 -0.151853 0.030386 0.151843 0.119003 -0.019913 -0.032872 0.013537 0.040938 0.078245 0.004616 -0.046330 -0.186425 0.009509 0.185284 0.200096 0.005319 -0.095603 0.026258 0.049865 0.058285 0.011946 0.001720 -0.200813 -0.034672 0.153352 0.243475 0.088942 -0.122680 -0.040852 0.000996 0.027009 0.007251 0.015506 -0.227641 -0.096086 0.077630 0.233859 0.182039 -0.022305 -0.106408 -0.014616 0.033564 0.002116 0.013826 -0.194741 -0.119380 -0.097914 0.128991 0.161256 0.065990 -0.009649 -0.014865 -0.001926 -0.038873 0.046100 -0.131181 -0.037115 -0.208423 -0.074910 0.038370 0.060891 0.062295 0.040574 0.017172 -0.005813 0.030025 -0.123647 0.022434 -0.096390 -0.169849 -0.155739 -0.019705 0.072689 0.083167 0.069289 0.060672 0.007498 -0.181767 -0.078387 -0.109109 -0.145847 -0.139493 -0.086060 -0.033676 0.022883 0.042756 0.078807 -0.000870 -0.087451 0.035668 0.034352 -0.005475 -0.002975 0.027061 0.037853 0.032977 0.031228 0.014559
3 11 11 2 2 0 0.259110 13.591304 -5.680955 11 11 5 0.001019 -0.011840 0.098092 0.053590 0.000125 -0.049693 -0.111459 -0.089173 -0.075840 -0.142558 -0.079042 -0.020531 -0.062352 -0.000842 -0.030872 -0.024987 0.054250 0.133732 0.205709 0.256510 0.167498 0.286865 0.006553 -0.048319 0.033570 0.009222 0.040333 0.072617 0.046326 -0.010144 -0.000205 -0.032410 0.001303 -0.000918 -0.050712 0.009193 -0.022796 0.118685 0.138305 0.040946 -0.050214 -0.050302 -0.034739 -0.004664 0.004289 0.007529 0.044226 0.082261 0.194104 -0.005143 -0.114492 -0.124481 -0.072713 -0.065813 0.047719 -0.003448 0.047509 0.076519 0.173045 0.026979 -0.238807 -0.138952 -0.032227 0.010314 -0.044823 0.112087 -0.038708 0.067468 0.099958 0.153679 -0.142199 -0.268290 -0.033868 0.007266 0.038080 -0.069530 0.032380 -0.007804 0.066182 0.121761 0.095763 -0.164570 -0.181157 -0.001176 -0.039541 0.024337 -0.068909 0.039717 -0.005093 0.077494 0.090830 0.019572 -0.132621 -0.101163 -0.021018 -0.069853 -0.053513 -0.154831 0.069686 -0.020220 0.073828 0.054584 0.026991 -0.051658 -0.036766 0.029945 -0.040521 -0.028652 -0.054207 0.005797 -0.027448 0.066125 0.027320 -0.057769 -0.066195 0.016498 0.061969 -0.093604 -0.062659 -0.162218 0.133017
2 1 0.196996 8.793545 -4.730062 11 11 5 -0.000870 -0.087451 0.035668 0.034352 -0.005475 -0.002975 0.027061 0.037853 0.032977 0.031228 0.014559 0.007498 -0.181767 -0.078387 -0.109109 -0.145847 -0.139493 -0.086060 -0.033676 0.022883 0.042756 0.078807 0.030025 -0.123647 0.022434 -0.096390 -0.169849 -0.155739 -0.019705 0.072689 0.083167 0.069289 0.060672 0.046100 -0.131181 -0.037115 -0.208423 -0.074910 0.038370 0.060891 0.062295 0.040574 0.017172 -0.005813 0.013826 -0.194741 -0.119380 -0.097914 0.128991 0.161256 0.065990 -0.009649 -0.014865 -0.001926 -0.038873 0.015506 -0.227641 -0.096086 0.077630 0.233859 0.182039 -0.022305 -0.106408 -0.014616 0.033564 0.002116 0.001720 -0.200813 -0.034672 0.153352 0.243475 0.088942 -0.122680 -0.040852 0.000996 0.027009 0.007251 -0.046330 -0.186425 0.009509 0.185284 0.200096 0.005319 -0.095603 0.026258 0.049865 0.058285 0.011946 -0.034048 -0.151853 0.030386 0.151843 0.119003 -0.019913 -0.032872 0.013537 0.040938 0.078245 0.004616 -0.045532 -0.136490 -0.001702 0.113738 0.092326 0.015315 0.024025 0.046474 0.064100 0.099514 0.020830 0.013831 -0.028865 0.028508 0.031279 -0.023129 0.014394 0.017833 0.020322 0.028058 0.045902 -0.028352
3 11 11 2 2 0 0.186287 11.712082 -5.018926 11 11 5 -0.122480 -0.076055 -0.055024 -0.064067 -0.088356 -0.063206 0.044665 0.062132 0.031418 -0.078660 0.184522 0.103182 0.030569 0.012037 -0.008896 -0.036350 0.012088 0.042192 -0.056879 -0.020282 -0.037404 0.138549 0.002151 -0.041417 -0.013229 -0.023571 -0.036009 0.082495 0.058581 -0.073872 -0.019359 -0.019373 0.012304 -0.016872 -0.013923 0.010907 -0.004304 0.051568 0.096957 -0.050659 -0.048876 0.018671 -0.016581 -0.097784 0.016910 -0.002980 0.006460 -0.015495 0.122016 0.038868 -0.218191 -0.002840 0.130960 -0.001275 -0.090759 0.018358 -0.042930 -0.002390 -0.009710 0.175777 0.069515 -0.269542 -0.022482 0.211050 0.022106 -0.119651 0.020945 -0.055163 0.039374 0.041824 0.178913 0.140639 -0.247578 -0.148725 0.115760 0.030135 -0.141065 0.010616 -0.044107 0.045482 0.030042 0.110082 0.128945 -0.180681 -0.204712 -0.002415 0.031089 -0.061656 0.025166 -0.025990 0.032820 0.015856 0.106638 0.163028 -0.038399 -0.172091 -0.068097 -0.023836 -0.003879 0.027734 -0.021398 0.031583 0.015864 0.072207 0.099225 -0.030945 -0.219538 -0.117986 -0.044745 -0.020380 0.083637 -0.039341 -0.017427 0.022429 0.109506 0.161624 0.208438 0.057966 -0.057823 -0.093367 0.098504
2 1 0.120075 6.957887 -4.389416 11 11 5 -0.034155 0.062102 0.027669 0.040784 0.014902 -0.020417 -0.041561 -0.006652 0.001745 0.003544 -0.043886 0.019589 0.010029 0.005843 0.005972 -0.021071 -0.023670 -0.001306 0.027883 -0.003999 0.019857 -0.014433 0.008022 0.008372 0.012367 0.034268 -0.006883 -0.006489 0.008796 0.003112 -0.000069 0.026604 -0.016050 -0.014095 -0.026534 0.002286 0.014084 -0.041709 0.024613 0.018300 -0.013305 0.022629 0.074462 0.001499 0.027718 -0.019648 -0.005029 -0.052111 -0.083872 0.105646 0.035210 -0.059769 0.003632 0.095227 0.027858 0.021814 -0.047825 -0.009170 -0.124281 -0.087184 0.191270 0.090342 -0.114810 0.020370 0.088383 0.042752 0.006256 -0.076661 -0.005492 -0.159026 -0.059475 0.251179 0.176398 -0.101207 -0.044607 0.078877 0.066352 0.002327 -0.122141 -0.064263 -0.172266 -0.103084 0.204028 0.249412 -0.012679 -0.122961 0.068220 0.073797 0.045161 -0.087958 -0.031169 -0.077716 -0.047123 0.167287 0.257321 0.072936 -0.140826 -0.003007 0.024894 -0.097969 -0.262373 -0.200669 -0.224123 -0.203979 0.062125 0.250687 0.155270 -0.036293 -0.004384 0.013697 0.046403 0.001490 0.015637 -0.042918 -0.117983 -0.112433 0.071569 0.127444 0.021425 -0.000855 -0.084125
3 11 11 2 2 0 0.206211 12.019035 -4.939878 11 11 5 -0.158655 -0.068029 -0.102264 -0.072242 0.015834 0.073070 0.021534 -0.041282 0.039142 -0.053414 0.133725 0.130625 0.014955 -0.012838 0.018674 0.019678 -0.025968 -0.054652 -0.042093 0.108913 -0.019331 0.111251 -0.027419 -0.036643 -0.047727 0.067856 0.063508 -0.056211 -0.054636 -0.019111 0.060560 -0.080398 0.108127 -0.041162 0.013226 0.012148 0.096117 -0.012007 -0.098402 0.045805 0.033059 -0.017990 -0.140130 0.013571 -0.009862 0.020404 0.061005 0.084452 -0.137746 -0.144070 0.179805 0.072025 -0.059634 -0.125567 -0.011909 -0.011109 0.019467 0.074946 0.133849 -0.149971 -0.180324 0.226365 0.090673 -0.089705 -0.097461 0.057221 -0.025524 0.054254 0.071673 0.168215 -0.091891 -0.254072 0.114764 0.091734 -0.082026 -0.109588 0.021154 -0.025439 0.061305 0.052731 0.144526 -0.047408 -0.244707 -0.026020 0.062883 -0.041003 -0.149327 0.000004 -0.008611 0.041262 0.066554 0.136055 0.038130 -0.138448 -0.096075 -0.033664 -0.003596 -0.040243 0.109173 0.014355 0.020359 0.054177 0.072405 0.010734 -0.152670 -0.158522 -0.076764 0.041764 -0.035477 -0.001213 0.029094 -0.025378 0.084334 0.132538 0.205100 0.119400 -0.039385 -0.105652 0.001361 -0.065128 0.136163
2 1 0.127639 7.453264 -4.353604 11 11 5 -0.007043 0.066447 0.018474 -0.003955 -0.054230 -0.024205 -0.005901 0.015205 -0.020095 -0.029237 -0.005403 -0.007601 0.000816 -0.009923 -0.041296 -0.012604 0.008300 0.017606 -0.012398 -0.025799 0.003979 0.009399 -0.013948 0.023064 0.003672 -0.006236 0.038896 -0.005430 0.015572 0.007247 -0.007463 0.019694 -0.021667 -0.008873 -0.017122 -0.043062 0.003188 0.031149 -0.038076 0.002892 0.025925 0.038513 0.045158 0.007066 0.012071 -0.072419 -0.085744 0.062638 0.066076 -0.076498 -0.014220 0.027079 0.061610 0.056657 -0.000451 0.017710 -0.166991 -0.121193 0.129373 0.125240 -0.065987 -0.058602 0.033074 0.067888 0.092608 0.005774 0.000679 -0.191264 -0.102829 0.164731 0.203060 -0.017960 -0.122730 0.017249 0.070348 0.128216 0.012051 -0.011669 -0.249293 -0.122247 0.112399 0.242482 0.072247 -0.143320 -0.043966 0.064093 0.124459 0.041174 0.033488 -0.197344 -0.061198 0.086731 0.242296 0.139404 -0.081218 -0.109426 0.028522 0.079522 0.013097 -0.138396 -0.334118 -0.228371 -0.041638 0.196402 0.190527 0.014337 -0.085061 -0.020649 0.051825 -0.000263 0.067401 -0.059234 -0.073887 -0.145670 0.012425 0.141923 0.079872 -0.023535 -0.056273 -0.016551 -0.029237
3 11 11 2 2 0 0.186287 11.712082 -5.018926 11 11 5 0.083637 -0.039341 -0.017427 0.022429 0.109506 0.161624 0.208438 0.057966 -0.057823 -0.093367 0.098504 0.027734 -0.021398 0.031583 0.015864 0.072207 0.099225 -0.030945 -0.219538 -0.117986 -0.044745 -0.020380 0.025166 -0.025990 0.032820 0.015856 0.106638 0.163028 -0.038399 -0.172091 -0.068097 -0.023836 -0.003879 0.010616 -0.044107 0.045482 0.030042 0.110082 0.128945 -0.180681 -0.204712 -0.002415 0.031089 -0.061656 0.020945 -0.055163 0.039374 0.041824 0.178913 0.140639 -0.247578 -0.148725 0.115760 0.030135 -0.141065 0.018358 -0.042930 -0.002390 -0.009710 0.175777 0.069515 -0.269542 -0.022482 0.211050 0.022106 -0.119651 0.016910 -0.002980 0.006460 -0.015495 0.122016 0.038868 -0.218191 -0.002840 0.130960 -0.001275 -0.090759 -0.016872 -0.013923 0.010907 -0.004304 0.051568 0.096957 -0.050659 -0.048876 0.018671 -0.016581 -0.097784 0.002151 -0.041417 -0.013229 -0.023571 -0.036009 0.082495 0.058581 -0.073872 -0.019359 -0.019373 0.012304 0.103182 0.030569 0.012037 -0.008896 -0.036350 0.012088 0.042192 -0.056879 -0.020282 -0.037404 0.138549 -0.122480 -0.076055 -0.055024 -0.064067 -0.088356 -0.063206 0.044665 0.062132 0.031418 -0.078660 0.184522
2 1 0.120075 6.957887 -4.389416 11 11 5 0.046403 0.001490 0.015637 -0.042918 -0.117983 -0.112433 0.071569 0.127444 0.021425 -0.000855 -0.084125 -0.097969 -0.262373 -0.200669 -0.224123 -0.203979 0.062125 0.250687 0.155270 -0.036293 -0.004384 0.013697 0.045161 -0.087958 -0.031169 -0.077716 -0.047123 0.167287 0.257321 0.072936 -0.140826 -0.003007 0.024894 0.002327 -0.122141 -0.064263 -0.172266 -0.103084 0.204028 0.249412 -0.012679 -0.122961 0.068220 0.073797 0.006256 -0.076661 -0.005492 -0.159026 -0.059475 0.251179 0.176398 -0.101207 -0.044607 0.078877 0.066352 0.021814 -0.047825 -0.009170 -0.124281 -0.087184 0.191270 0.090342 -0.114810 0.020370 0.088383 0.042752 0.027718 -0.019648 -0.005029 -0.052111 -0.083872 0.105646 0.035210 -0.059769 0.003632 0.095227 0.027858 -0.014095 -0.026534 0.002286 0.014084 -0.041709 0.024613 0.018300 -0.013305 0.022629 0.074462 0.001499 0.008022 0.008372 0.012367 0.034268 -0.006883 -0.006489 0.008796 0.003112 -0.000069 0.026604 -0.016050 0.019589 0.010029 0.005843 0.005972 -0.021071 -0.023670 -0.001306 0.027883 -0.003999 0.019857 -0.014433 -0.034155 0.062102 0.027669 0.040784 0.014902 -0.020417 -0.041561 -0.006652 0.001745 0.003544 -0.043886
3 11 11 2 2 0 0.206211 12.019035 -4.939878 11 11 5 0.029094 -0.025378 0.084334 0.132538 0.205100 0.119400 -0.039385 -0.105652 0.001361 -0.065128 0.136163 0.014355 0.020359 0.054177 0.072405 0.010734 -0.152670 -0.158522 -0.076764 0.041764 -0.035477 -0.001213 -0.008611 0.041262 0.066554 0.136055 0.038130 -0.138448 -0.096075 -0.033664 -0.003596 -0.040243 0.109173 -0.025439 0.061305 0.052731 0.144526 -0.047408 -0.244707 -0.026020 0.062883 -0.041003 -0.149327 0.000004 -0.025524 0.054254 0.071673 0.168215 -0.091891 -0.254072 0.114764 0.091734 -0.082026 -0.109588 0.021154 -0.011109 0.019467 0.074946 0.133849 -0.149971 -0.180324 0.226365 0.090673 -0.089705 -0.097461 0.057221 -0.009862 0.020404 0.061005 0.084452 -0.137746 -0.144070 0.179805 0.072025 -0.059634 -0.125567 -0.011909 -0.041162 0.013226 0.012148 0.096117 -0.012007 -0.098402 0.045805 0.033059 -0.017990 -0.140130 0.013571 -0.027419 -0.036643 -0.047727 0.067856 0.063508 -0.056211 -0.054636 -0.019111 0.060560 -0.080398 0.108127 0.130625 0.014955 -0.012838 0.018674 0.019678 -0.025968 -0.054652 -0.042093 0.108913 -0.019331 0.111251 -0.158655 -0.068029 -0.102264 -0.072242 0.015834 0.073070 0.021534 -0.041282 0.039142 -0.053414 0.133725
2 1 0.127639 7.453264 -4.353604 11 11 5 0.067401 -0.059234 -0.073887 -0.145670 0.012425 0.141923 0.079872 -0.023535 -0.056273 -0.016551 -0.029237 -0.138396 -0.334118 -0.228371 -0.041638 0.196402 0.190527 0.014337 -0.085061 -0.020649 0.051825 -0.000263 0.033488 -0.197344 -0.061198 0.086731 0.242296 0.139404 -0.081218 -0.109426 0.028522 0.079522 0.013097 -0.011669 -0.249293 -0.122247 0.112399 0.242482 0.072247 -0.143320 -0.043966 0.064093 0.124459 0.041174 0.000679 -0.191264 -0.102829 0.164731 0.203060 -0.017960 -0.122730 0.017249 0.070348 0.128216 0.012051 0.017710 -0.166991 -0.121193 0.129373 0.125240 -0.065987 -0.058602 0.033074 0.067888 0.092608 0.005774 0.012071 -0.072419 -0.085744 0.062638 0.066076 -0.076498 -0.014220 0.027079 0.061610 0.056657 -0.000451 -0.008873 -0.017122 -0.043062 0.003188 0.031149 -0.038076 0.002892 0.025925 0.038513 0.045158 0.007066 -0.013948 0.023064 0.003672 -0.006236 0.038896 -0.005430 0.015572 0.007247 -0.007463 0.019694 -0.021667 -0.007601 0.000816 -0.009923 -0.041296 -0.012604 0.008300 0.017606 -0.012398 -0.025799 0.003979 0.009399 -0.007043 0.066447 0.018474 -0.003955 -0.054230 -0.024205 -0.005901 0.015205 -0.020095 -0.029237 -0.005403
3 11 11 2 2 0 0.273972 12.948619 -5.029197 11 11 5 -0.223240 0.070517 -0.058009 -0.031474 0.002954 0.050272 0.039809 -0.013047 -0.025761 -0.005654 -0.072628 -0.068861 0.092111 -0.005075 0.018230 -0.015074 -0.021072 -0.002888 0.003105 -0.010916 0.005462 -0.048517 -0.075409 0.028852 -0.016555 -0.004752 0.010756 0.064861 0.077906 0.022626 -0.012270 0.024629 -0.052527 0.063812 -0.013422 -0.034902 -0.067009 -0.011849 0.085810 0.044555 0.004599 0.009141 0.045594 -0.017174 0.096950 -0.076606 -0.047747 -0.041193 0.089938 0.062207 -0.015600 0.077993 0.071039 0.026179 0.017312 0.047825 -0.079928 0.012194 0.091087 0.082229 -0.259087 -0.227389 0.112965 0.131769 0.030336 0.089523 0.046862 -0.054315 0.043962 0.106122 -0.070900 -0.335147 -0.238495 -0.013748 0.070822 0.030778 0.101766 0.051153 -0.031391 0.066507 0.044171 -0.058541 0.049728 0.177738 -0.007964 -0.018846 0.017852 0.085950 0.043914 -0.059473 0.062911 0.026094 -0.125814 -0.119347 0.010732 0.018261 0.032161 0.000938 0.059794 0.062122 -0.102975 0.081838 0.089629 -0.080713 -0.297695 -0.206490 0.017753 0.077103 -0.015904 0.049311 0.305606 -0.172944 -0.081675 -0.063671 -0.050159 -0.034800 0.068031 0.060386 0.011337 0.004851 0.115312
2 1 0.095517 8.062213 -4.246546 11 11 5 -0.053993 0.013131 0.002224 0.029077 0.008405 -0.007813 -0.021525 -0.011601 0.010892 -0.002090 -0.048665 0.014189 0.002326 0.009960 0.011495 0.011106 0.017875 0.004769 -0.013400 0.013984 -0.021835 0.004775 -0.035569 -0.020707 -0.014172 -0.026594 -0.016488 -0.025644 -0.020934 -0.011318 0.021603 -0.014710 0.052139 0.001079 0.022271 0.038348 0.002965 -0.046399 -0.061117 -0.056960 -0.070977 0.021930 -0.031217 0.043654 0.007329 0.028998 0.023958 -0.062366 -0.033032 0.051553 0.094454 -0.021524 -0.172415 -0.125424 0.108212 -0.017536 0.040140 -0.014506 -0.043372 0.033617 -0.000301 0.179003 0.218280 -0.063800 -0.344874 0.068742 -0.018011 0.052569 -0.055409 0.024717 0.075962 -0.070967 0.125844 0.202086 0.074673 -0.276797 -0.075658 -0.007946 0.060956 -0.046555 0.043311 0.045909 -0.017592 0.117349 0.038939 0.044621 -0.172782 -0.147399 -0.008399 0.065073 -0.054580 0.030897 0.024923 0.014744 0.173674 0.054226 0.021759 -0.191280 -0.097186 0.024983 0.097521 -0.014223 0.029187 0.071464 0.126635 0.293286 0.183558 -0.014474 -0.301969 -0.114599 -0.015321 0.123457 -0.022987 -0.096431 -0.052216 0.069124 0.146586 -0.000302 -0.138926 -0.125356 -0.000274
3 11 11 2 2 0 0.273972 12.948619 -5.029197 11 11 5 0.305606 -0.172944 -0.081675 -0.063671 -0.050159 -0.034800 0.068031 0.060386 0.011337 0.004851 0.115312 0.062122 -0.102975 0.081838 0.089629 -0.080713 -0.297695 -0.206490 0.017753 0.077103 -0.015904 0.049311 0.043914 -0.059473 0.062911 0.026094 -0.125814 -0.119347 0.010732 0.018261 0.032161 0.000938 0.059794 0.051153 -0.031391 0.066507 0.044171 -0.058541 0.049728 0.177738 -0.007964 -0.018846 0.017852 0.085950 0.046862 -0.054315 0.043962 0.106122 -0.070900 -0.335147 -0.238495 -0.013748 0.070822 0.030778 0.101766 0.047825 -0.079928 0.012194 0.091087 0.082229 -0.259087 -0.227389 0.112965 0.131769 0.030336 0.089523 0.096950 -0.076606 -0.047747 -0.041193 0.089938 0.062207 -0.015600 0.077993 0.071039 0.026179 0.017312 0.063812 -0.013422 -0.034902 -0.067009 -0.011849 0.085810 0.044555 0.004599 0.009141 0.045594 -0.017174 -0.075409 0.028852 -0.016555 -0.004752 0.010756 0.064861 0.077906 0.022626 -0.012270 0.024629 -0.052527 -0.068861 0.092111 -0.005075 0.018230 -0.015074 -0.021072 -0.002888 0.003105 -0.010916 0.005462 -0.048517 -0.223240 0.070517 -0.058009 -0.031474 0.002954 0.050272 0.039809 -0.013047 -0.025761 -0.005654 -0.072628
2 1 0.095517 8.062213 -4.246546 11 11 5 -0.015321 0.123457 -0.022987 -0.096431 -0.052216 0.069124 0.146586 -0.000302 -0.138926 -0.125356 -0.000274 0.024983 0.097521 -0.014223 0.029187 0.071464 0.126635 0.293286 0.183558 -0.014474 -0.301969 -0.114599 -0.008399 0.065073 -0.054580 0.030897 0.024923 0.014744 0.173674 0.054226 0.021759 -0.191280 -0.097186 -0.007946 0.060956 -0.046555 0.043311 0.045909 -0.017592 0.117349 0.038939 0.044621 -0.172782 -0.147399 -0.018011 0.052569 -0.055409 0.024717 0.075962 -0.070967 0.125844 0.202086 0.074673 -0.276797 -0.075658 -0.017536 0.040140 -0.014506 -0.043372 0.033617 -0.000301 0.179003 0.218280 -0.063800 -0.344874 0.068742 0.007329 0.028998 0.023958 -0.062366 -0.033032 0.051553 0.094454 -0.021524 -0.172415 -0.125424 0.108212 0.001079 0.022271 0.038348 0.002965 -0.046399 -0.061117 -0.056960 -0.070977 0.021930 -0.031217 0.043654 -0.035569 -0.020707 -0.014172 -0.026594 -0.016488 -0.025644 -0.020934 -0.011318 0.021603 -0.014710 0.052139 0.014189 0.002326 0.009960 0.011495 0.011106 0.017875 0.004769 -0.013400 0.013984 -0.021835 0.004775 -0.053993 0.013131 0.002224 0.029077 0.008405 -0.007813 -0.021525 -0.011601 0.010892 -0.002090 -0.048665
3 11 11 2 2 0 0.340017 14.137682 -5.932109 11 11 5 -0.024370 0.017145 0.048428 -0.045133 -0.180805 -0.126396 -0.110508 -0.080300 0.084066 0.087315 0.175838 0.071043 0.003299 0.016281 0.010987 -0.032695 0.066741 0.122405 0.070400 -0.000041 -0.017253 -0.001254 0.047675 -0.025407 0.035057 0.022217 -0.229994 -0.403675 -0.185946 0.080601 0.041850 0.001750 0.114098 0.047692 -0.093888 -0.034741 -0.014376 -0.128161 -0.118735 -0.055536 0.061026 0.055036 -0.034696 0.057077 0.067828 -0.116355 -0.067291 -0.066242 -0.051574 0.209021 0.210621 -0.034535 -0.004820 0.025494 0.101637 0.098252 -0.081942 -0.056161 -0.037546 -0.101925 -0.229795 -0.136918 0.058632 0.032561 0.055784 0.024787 0.148983 -0.069305 0.010394 -0.055716 0.051130 -0.145879 -0.040718 0.079191 -0.001645 0.110919 -0.041030 0.139900 -0.042375 0.083054 -0.065309 -0.077965 -0.015032 0.017516 -0.016835 -0.016897 0.036806 -0.105461 0.115238 -0.044969 -0.001391 -0.030327 -0.045313 -0.073694 -0.065840 -0.044480 -0.014289 -0.042515 -0.053200 0.076791 0.041127 0.108466 0.070792 0.111906 0.145652 0.102713 0.024290 0.029927 -0.005913 0.076237 0.029817 -0.063159 -0.060282 -0.034007 0.046964 0.084779 0.074736 0.048601 0.056842 -0.021094 0.078243
2 1 0.111704 8.387926 -4.393632 11 11 5 -0.030673 0.038371 -0.001307 0.018236 -0.008843 -0.018744 0.023474 0.036012 0.026443 -0.167310 0.007784 0.001534 0.051901 -0.000656 0.038862 0.074183 0.116484 0.127293 0.003078 -0.030219 -0.250108 -0.125427 0.014548 0.072149 -0.021550 -0.006321 0.008410 0.167367 0.282977 0.131459 -0.026491 -0.286477 -0.096566 0.037325 0.120466 -0.023486 -0.049182 0.069474 0.199920 0.265545 0.052290 -0.105179 -0.322791 -0.075761 0.045748 0.149501 -0.010081 -0.055810 0.067850 0.107646 0.024491 -0.129119 -0.061738 -0.173354 0.003324 0.042373 0.134699 0.036019 -0.052426 -0.037064 -0.034912 -0.006525 -0.001757 0.046877 -0.099462 0.001429 0.016384 0.095827 0.060250 -0.032527 -0.100054 -0.016605 0.091893 0.071533 0.067518 -0.108590 -0.043743 -0.031801 0.044541 0.027294 -0.006832 -0.003436 0.018392 0.004990 -0.019144 0.002926 -0.147750 -0.022368 -0.053136 0.000667 0.009538 0.044531 0.102003 0.105859 0.060020 -0.010554 -0.012099 -0.124424 0.019576 -0.133577 -0.170401 -0.074444 -0.025617 0.043842 0.036553 0.014653 -0.000260 0.012776 -0.094549 0.057633 0.018431 -0.121041 -0.050733 -0.031954 0.012680 0.024299 0.044871 0.028124 0.021966 -0.099671 0.039535
3 11 11 2 2 0 0.340017 14.137682 -5.932109 11 11 5 0.029817 -0.063159 -0.060282 -0.034007 0.046964 0.084779 0.074736 0.048601 0.056842 -0.021094 0.078243 0.076791 0.041127 0.108466 0.070792 0.111906 0.145652 0.102713 0.024290 0.029927 -0.005913 0.076237 0.115238 -0.044969 -0.001391 -0.030327 -0.045313 -0.073694 -0.065840 -0.044480 -0.014289 -0.042515 -0.053200 0.139900 -0.042375 0.083054 -0.065309 -0.077965 -0.015032 0.017516 -0.016835 -0.016897 0.036806 -0.105461 0.148983 -0.069305 0.010394 -0.055716 0.051130 -0.145879 -0.040718 0.079191 -0.001645 0.110919 -0.041030 0.098252 -0.081942 -0.056161 -0.037546 -0.101925 -0.229795 -0.136918 0.058632 0.032561 0.055784 0.024787 0.067828 -0.116355 -0.067291 -0.066242 -0.051574 0.209021 0.210621 -0.034535 -0.004820 0.025494 0.101637 0.047692 -0.093888 -0.034741 -0.014376 -0.128161 -0.118735 -0.055536 0.061026 0.055036 -0.034696 0.057077 0.047675 -0.025407 0.035057 0.022217 -0.229994 -0.403675 -0.185946 0.080601 0.041850 0.001750 0.114098 0.071043 0.003299 0.016281 0.010987 -0.032695 0.066741 0.122405 0.070400 -0.000041 -0.017253 -0.001254 -0.024370 0.017145 0.048428 -0.045133 -0.180805 -0.126396 -0.110508 -0.080300 0.084066 0.087315 0.175838
2 1 0.111704 8.387926 -4.393632 11 11 5 0.018431 -0.121041 -0.050733 -0.031954 0.012680 0.024299 0.044871 0.028124 0.021966 -0.099671 0.039535 -0.133577 -0.170401 -0.074444 -0.025617 0.043842 0.036553 0.014653 -0.000260 0.012776 -0.094549 0.057633 -0.053136 0.000667 0.009538 0.044531 0.102003 0.105859 0.060020 -0.010554 -0.012099 -0.124424 0.019576 -0.031801 0.044541 0.027294 -0.006832 -0.003436 0.018392 0.004990 -0.019144 0.002926 -0.147750 -0.022368 0.016384 0.095827 0.060250 -0.032527 -0.100054 -0.016605 0.091893 0.071533 0.067518 -0.108590 -0.043743 0.042373 0.134699 0.036019 -0.052426 -0.037064 -0.034912 -0.006525 -0.001757 0.046877 -0.099462 0.001429 0.045748 0.149501 -0.010081 -0.055810 0.067850 0.107646 0.024491 -0.129119 -0.061738 -0.173354 0.003324 0.037325 0.120466 -0.023486 -0.049182 0.069474 0.199920 0.265545 0.052290 -0.105179 -0.322791 -0.075761 0.014548 0.072149 -0.021550 -0.006321 0.008410 0.167367 0.282977 0.131459 -0.026491 -0.286477 -0.096566 0.001534 0.051901 -0.000656 0.038862 0.074183 0.116484 0.127293 0.003078 -0.030219 -0.250108 -0.125427 -0.030673 0.038371 -0.001307 0.018236 -0.008843 -0.018744 0.023474 0.036012 0.026443 -0.167310 0.007784
3 11 11 2 2 0 0.310483 14.627354 -5.375082 11 11 5 -0.277864 0.081778 -0.023864 -0.047318 -0.070356 -0.004330 0.079274 0.073222 0.063504 0.055790 -0.030521 0.126858 0.068350 -0.037196 -0.038437 0.002880 0.075994 0.033232 -0.079020 -0.006569 0.049695 0.094725 -0.005527 0.008174 -0.042019 -0.007949 0.055986 0.071274 -0.109142 -0.267315 -0.114639 0.030592 0.123980 0.040518 -0.007117 -0.000951 -0.001230 0.072504 -0.012581 -0.092315 -0.008912 -0.032866 -0.125486 0.159596 0.041139 -0.050670 0.003531 -0.002451 0.099594 -0.040380 -0.134643 0.117875 0.199283 -0.058045 0.078518 0.075266 -0.036242 0.005782 -0.024145 0.128166 0.026016 -0.294342 -0.255040 0.030510 0.044873 0.033111 0.102819 0.008772 -0.019393 -0.105223 0.061996 0.033899 -0.259765 -0.262972 -0.014720 0.046228 0.049158 0.081681 0.002946 -0.041954 -0.119855 -0.035717 -0.026522 -0.039168 0.143518 0.171653 -0.066006 0.045098 0.085371 0.041502 -0.001925 -0.033638 -0.065388 -0.008774 -0.022569 0.025928 -0.010097 -0.026359 0.107905 0.081303 0.080984 -0.021530 -0.061876 -0.123288 -0.028716 -0.006637 -0.140066 -0.092357 0.018770 0.063461 0.006877 0.099425 0.091907 0.100886 0.035698 -0.020671 0.044712 0.039163 0.042772 0.028459 0.000183
2 1 0.095773 6.809407 -3.986456 11 11 5 -0.001385 -0.052703 0.005039 0.020606 -0.011589 -0.044621 -0.060765 -0.055850 -0.019011 -0.137223 0.102874 -0.011561 -0.056874 0.035191 0.023407 -0.035750 -0.003024 0.033502 0.047189 0.104505 -0.104659 -0.098844 -0.028499 -0.055416 0.046300 -0.019447 -0.044152 0.062219 0.024097 0.014175 0.135876 0.021193 -0.060552 -0.048078 -0.035409 0.066680 -0.033051 -0.042247 0.072955 -0.003575 0.001155 0.043377 -0.044608 -0.043559 -0.048959 -0.010585 0.087908 -0.025631 -0.063771 0.082175 0.012942 0.119076 0.122879 -0.139127 -0.082482 -0.064841 0.017352 0.120952 0.000907 -0.066864 0.099235 -0.037938 0.153598 0.299946 -0.097170 -0.183712 -0.076713 0.027837 0.148342 0.051149 -0.104482 -0.002197 0.018363 0.247085 0.309935 -0.086417 -0.190496 -0.080252 0.023602 0.154103 0.082426 -0.089397 -0.092089 0.096510 0.184970 0.079362 -0.209652 -0.076838 -0.066285 0.041698 0.161409 0.095754 -0.024550 -0.122664 0.011709 0.007060 -0.040816 -0.079829 0.016528 -0.188130 -0.090692 0.123037 0.091082 0.028938 -0.098614 -0.057674 -0.010107 0.052678 0.003483 -0.015790 0.027617 -0.181520 -0.015426 0.010048 0.042899 0.002487 -0.016516 -0.027110 -0.025662 -0.076333 0.002362
3 11 11 2 2 0 0.297317 15.189876 -5.398768 11 11 5 -0.077679 -0.078057 -0.035288 0.021513 0.095618 0.083689 0.036447 0.022887 -0.012516 0.016240 -0.158964 0.062129 -0.054644 0.019243 0.025845 -0.007799 -0.018553 0.030616 0.042744 0.050172 0.040798 0.051072 -0.012540 -0.001643 0.099993 -0.008971 -0.202760 -0.210953 -0.000818 0.057881 0.049173 0.031407 0.040305 0.031008 0.053353 0.033409 -0.116897 -0.070242 -0.087543 -0.090774 0.029572 0.050591 0.047798 0.081156 0.004179 0.027816 0.012014 -0.059234 0.133234 0.156869 0.026674 0.004828 0.038419 0.012912 0.048271 0.020450 -0.007283 0.081364 -0.071433 -0.256209 -0.209887 0.085903 0.040719 0.006508 -0.028150 0.081784 0.027898 -0.064536 0.073299 -0.085637 -0.360474 -0.298644 0.101679 0.049419 0.020197 -0.033569 0.094910 -0.023911 -0.128269 0.004633 -0.055295 0.076652 0.151267 0.082089 -0.038147 0.025678 -0.038443 0.109457 0.080496 -0.124038 0.003035 -0.072068 0.068028 0.103106 -0.026616 -0.003510 0.066598 0.063345 0.084585 0.098251 -0.130461 -0.022379 -0.082558 -0.116548 -0.159113 -0.053549 0.044221 0.006985 0.034158 -0.127311 0.267123 -0.063811 0.099475 -0.003334 0.043634 0.035762 0.032585 0.022820 0.014793 0.048897 -0.030620
2 1 0.131537 9.051968 -4.506198 11 11 5 -0.025920 0.053767 -0.013583 -0.050690 -0.036335 -0.041475 -0.065200 -0.022161 0.069514 0.021770 0.036893 0.008817 0.026204 -0.021277 0.013299 0.064680 0.072034 0.023773 -0.133892 -0.094312 -0.056056 0.028385 -0.012041 -0.002337 0.020317 0.026028 0.020994 0.102656 0.142985 0.038063 -0.106689 -0.188645 0.072956 -0.012767 0.019732 0.018448 0.022210 0.013067 0.036623 0.085424 0.069770 -0.005373 -0.286534 -0.017091 -0.002072 0.022809 0.006938 0.036166 0.061318 0.052002 0.022498 -0.003263 0.031989 -0.257941 -0.076418 0.016166 0.029025 -0.001571 0.056011 0.057554 0.197971 0.178971 -0.022095 -0.056370 -0.286793 -0.081790 0.036316 0.035763 -0.050256 0.007247 0.116992 0.285705 0.230773 -0.058716 -0.133650 -0.273392 -0.039636 0.046890 0.054718 -0.070426 0.028669 0.150431 0.181771 -0.004792 -0.189851 -0.024273 -0.209283 0.005436 0.051314 0.066488 -0.057146 -0.010414 0.043519 -0.032549 -0.103225 -0.008287 0.076331 -0.147712 0.043668 0.042825 0.084181 -0.029300 -0.039906 -0.007795 0.033982 0.062784 0.056154 0.012447 -0.124390 -0.004829 -0.044180 0.063541 0.007211 0.002616 -0.016565 -0.001132 0.013155 0.013625 -0.017526 -0.069486 0.017030
3 11 11 2 2 0 0.310483 14.627354 -5.375082 11 11 5 0.006877 0.099425 0.091907 0.100886 0.035698 -0.020671 0.044712 0.039163 0.042772 0.028459 0.000183 0.081303 0.080984 -0.021530 -0.061876 -0.123288 -0.028716 -0.006637 -0.140066 -0.092357 0.018770 0.063461 0.085371 0.041502 -0.001925 -0.033638 -0.065388 -0.008774 -0.022569 0.025928 -0.010097 -0.026359 0.107905 0.081681 0.002946 -0.041954 -0.119855 -0.035717 -0.026522 -0.039168 0.143518 0.171653 -0.066006 0.045098 0.102819 0.008772 -0.019393 -0.105223 0.061996 0.033899 -0.259765 -0.262972 -0.014720 0.046228 0.049158 0.075266 -0.036242 0.005782 -0.024145 0.128166 0.026016 -0.294342 -0.255040 0.030510 0.044873 0.033111 0.041139 -0.050670 0.003531 -0.002451 0.099594 -0.040380 -0.134643 0.117875 0.199283 -0.058045 0.078518 0.040518 -0.007117 -0.000951 -0.001230 0.072504 -0.012581 -0.092315 -0.008912 -0.032866 -0.125486 0.159596 -0.005527 0.008174 -0.042019 -0.007949 0.055986 0.071274 -0.109142 -0.267315 -0.114639 0.030592 0.123980 0.126858 0.068350 -0.037196 -0.038437 0.002880 0.075994 0.033232 -0.079020 -0.006569 0.049695 0.094725 -0.277864 0.081778 -0.023864 -0.047318 -0.070356 -0.004330 0.079274 0.073222 0.063504 0.055790 -0.030521
2 1 0.095773 6.809407 -3.986456 11 11 5 0.027617 -0.181520 -0.015426 0.010048 0.042899 0.002487 -0.016516 -0.027110 -0.025662 -0.076333 0.002362 -0.188130 -0.090692 0.123037 0.091082 0.028938 -0.098614 -0.057674 -0.010107 0.052678 0.003483 -0.015790 -0.066285 0.041698 0.161409 0.095754 -0.024550 -0.122664 0.011709 0.007060 -0.040816 -0.079829 0.016528 -0.080252 0.023602 0.154103 0.082426 -0.089397 -0.092089 0.096510 0.184970 0.079362 -0.209652 -0.076838 -0.076713 0.027837 0.148342 0.051149 -0.104482 -0.002197 0.018363 0.247085 0.309935 -0.086417 -0.190496 -0.064841 0.017352 0.120952 0.000907 -0.066864 0.099235 -0.037938 0.153598 0.299946 -0.097170 -0.183712 -0.048959 -0.010585 0.087908 -0.025631 -0.063771 0.082175 0.012942 0.119076 0.122879 -0.139127 -0.082482 -0.048078 -0.035409 0.066680 -0.033051 -0.042247 0.072955 -0.003575 0.001155 0.043377 -0.044608 -0.043559 -0.028499 -0.055416 0.046300 -0.019447 -0.044152 0.062219 0.024097 0.014175 0.135876 0.021193 -0.060552 -0.011561 -0.056874 0.035191 0.023407 -0.035750 -0.003024 0.033502 0.047189 0.104505 -0.104659 -0.098844 -0.001385 -0.052703 0.005039 0.020606 -0.011589 -0.044621 -0.060765 -0.055850 -0.019011 -0.137223 0.102874
3 11 11 2 2 0 0.297317 15.189876 -5.398768 11 11 5 0.267123 -0.063811 0.099475 -0.003334 0.043634 0.035762 0.032585 0.022820 0.014793 0.048897 -0.030620 0.098251 -0.130461 -0.022379 -0.082558 -0.116548 -0.159113 -0.053549 0.044221 0.006985 0.034158 -0.127311 0.080496 -0.124038 0.003035 -0.072068 0.068028 0.103106 -0.026616 -0.003510 0.066598 0.063345 0.084585 -0.023911 -0.128269 0.004633 -0.055295 0.076652 0.151267 0.082089 -0.038147 0.025678 -0.038443 0.109457 0.027898 -0.064536 0.073299 -0.085637 -0.360474 -0.298644 0.101679 0.049419 0.020197 -0.033569 0.094910 0.020450 -0.007283 0.081364 -0.071433 -0.256209 -0.209887 0.085903 0.040719 0.006508 -0.028150 0.081784 0.004179 0.027816 0.012014 -0.059234 0.133234 0.156869 0.026674 0.004828 0.038419 0.012912 0.048271 0.031008 0.053353 0.033409 -0.116897 -0.070242 -0.087543 -0.090774 0.029572 0.050591 0.047798 0.081156 -0.012540 -0.001643 0.099993 -0.008971 -0.202760 -0.210953 -0.000818 0.057881 0.049173 0.031407 0.040305 0.062129 -0.054644 0.019243 0.025845 -0.007799 -0.018553 0.030616 0.042744 0.050172 0.040798 0.051072 -0.077679 -0.078057 -0.035288 0.021513 0.095618 0.083689 0.036447 0.022887 -0.012516 0.016240 -0.158964
2 1 0.131537 9.051968 -4.506198 11 11 5 -0.044180 0.063541 0.007211 0.002616 -0.016565 -0.001132 0.013155 0.013625 -0.017526 -0.069486 0.017030 0.042825 0.084181 -0.029300 -0.039906 -0.007795 0.033982 0.062784 0.056154 0.012447 -0.124390 -0.004829 0.051314 0.066488 -0.057146 -0.010414 0.043519 -0.032549 -0.103225 -0.008287 0.076331 -0.147712 0.043668 0.046890 0.054718 -0.070426 0.028669 0.150431 0.181771 -0.004792 -0.189851 -0.024273 -0.209283 0.005436 0.036316 0.035763 -0.050256 0.007247 0.116992 0.285705 0.230773 -0.058716 -0.133650 -0.273392 -0.039636 0.016166 0.029025 -0.001571 0.056011 0.057554 0.197971 0.178971 -0.022095 -0.056370 -0.286793 -0.081790 -0.002072 0.022809 0.006938 0.036166 0.061318 0.052002 0.022498 -0.003263 0.031989 -0.257941 -0.076418 -0.012767 0.019732 0.018448 0.022210 0.013067 0.036623 0.085424 0.069770 -0.005373 -0.286534 -0.017091 -0.012041 -0.002337 0.020317 0.026028 0.020994 0.102656 0.142985 0.038063 -0.106689 -0.188645 0.072956 0.008817 0.026204 -0.021277 0.013299 0.064680 0.072034 0.023773 -0.133892 -0.094312 -0.056056 0.028385 -0.025920 0.053767 -0.013583 -0.050690 -0.036335 -0.041475 -0.065200 -0.022161 0.069514 0.021770 0.036893
3 11 11 2 2 0 0.343753 16.706010 -5.452573 11 11 5 -0.179362 0.074201 -0.096518 -0.054940 0.007958 0.072061 0.073978 0.037482 0.030822 0.036665 -0.104708 0.119608 -0.014982 -0.030538 0.014390 0.057573 0.001974 -0.052109 -0.003731 0.061742 0.023216 0.098873 0.032906 -0.063538 0.010777 0.051999 0.042998 -0.147171 -0.234950 -0.115856 0.086141 0.018786 0.076667 0.033784 -0.012239 0.043054 0.032703 -0.051492 -0.033894 0.083953 -0.057983 -0.049691 0.017955 0.087126 0.011759 -0.029123 0.005393 0.052756 -0.027562 -0.043366 0.160047 0.149874 -0.004511 -0.018549 0.076129 0.033879 -0.007287 -0.005461 0.080998 0.024003 -0.324357 -0.349074 -0.010967 0.111365 -0.047735 0.056747 0.069018 -0.032367 -0.048560 0.041730 0.043215 -0.268472 -0.329120 -0.006224 0.130182 -0.037648 0.067862 0.068964 -0.083615 -0.069181 -0.044809 -0.021042 0.001116 0.169392 0.149836 -0.019002 -0.037827 0.057213 0.108985 -0.054378 -0.004875 -0.067708 -0.015976 0.027940 0.128354 0.012955 -0.026419 0.050190 0.058210 0.129853 -0.066034 -0.015312 -0.102832 -0.050160 -0.067021 -0.130318 -0.086559 0.006927 0.035352 -0.029106 0.128098 0.038958 0.094793 0.014693 0.021297 0.040431 0.020979 0.029663 0.008863 0.041361 -0.002513
2 1 0.119115 8.582349 -4.235264 11 11 5 -0.021815 0.003010 0.026843 -0.003809 -0.044566 -0.041887 -0.032338 -0.049991 -0.040843 -0.059949 0.109206 -0.022217 0.021044 0.018703 -0.039919 -0.002106 0.031998 0.050144 0.065709 -0.020840 -0.253646 0.016799 -0.017912 0.024507 -0.017393 -0.025043 0.052834 0.019087 0.054584 0.129125 0.125605 -0.180554 -0.035116 -0.009190 0.031352 -0.020749 -0.009630 0.047430 -0.001681 0.010137 -0.004260 0.077043 -0.095861 -0.101195 0.003794 0.048401 -0.017943 -0.018061 0.046883 0.037451 0.113447 0.067940 -0.061177 -0.139017 -0.068716 0.000255 0.075098 -0.006633 -0.021815 0.099009 -0.062379 0.152324 0.279559 0.054057 -0.284854 -0.094401 -0.004054 0.092481 0.027660 -0.068540 0.024574 0.000841 0.230619 0.299878 0.037370 -0.328121 -0.072815 -0.010252 0.095278 0.066511 -0.076884 -0.062379 0.130051 0.217872 0.074797 -0.192851 -0.208987 -0.019366 0.006972 0.093347 0.071865 -0.029031 -0.107339 0.024220 0.022169 -0.114337 -0.037606 -0.065620 0.020943 -0.034695 0.059537 0.064716 0.024870 -0.071974 -0.065573 0.004449 0.034669 0.052304 -0.061859 -0.007266 -0.040096 -0.026823 0.007316 0.024536 0.022701 -0.018964 -0.013590 -0.017306 0.020985 -0.062085 -0.000989
3 11 11 2 2 0 0.343753 16.706010 -5.452573 11 11 5 0.128098 0.038958 0.094793 0.014693 0.021297 0.040431 0.020979 0.029663 0.008863 0.041361 -0.002513 0.129853 -0.066034 -0.015312 -0.102832 -0.050160 -0.067021 -0.130318 -0.086559 0.006927 0.035352 -0.029106 0.108985 -0.054378 -0.004875 -0.067708 -0.015976 0.027940 0.128354 0.012955 -0.026419 0.050190 0.058210 0.068964 -0.083615 -0.069181 -0.044809 -0.021042 0.001116 0.169392 0.149836 -0.019002 -0.037827 0.057213 0.069018 -0.032367 -0.048560 0.041730 0.043215 -0.268472 -0.329120 -0.006224 0.130182 -0.037648 0.067862 0.033879 -0.007287 -0.005461 0.080998 0.024003 -0.324357 -0.349074 -0.010967 0.111365 -0.047735 0.056747 0.011759 -0.029123 0.005393 0.052756 -0.027562 -0.043366 0.160047 0.149874 -0.004511 -0.018549 0.076129 0.033784 -0.012239 0.043054 0.032703 -0.051492 -0.033894 0.083953 -0.057983 -0.049691 0.017955 0.087126 0.032906 -0.063538 0.010777 0.051999 0.042998 -0.147171 -0.234950 -0.115856 0.086141 0.018786 0.076667 0.119608 -0.014982 -0.030538 0.014390 0.057573 0.001974 -0.052109 -0.003731 0.061742 0.023216 0.098873 -0.179362 0.074201 -0.096518 -0.054940 0.007958 0.072061 0.073978 0.037482 0.030822 0.036665 -0.104708
2 1 0.119115 8.582349 -4.235264 11 11 5 -0.040096 -0.026823 0.007316 0.024536 0.022701 -0.018964 -0.013590 -0.017306 0.020985 -0.062085 -0.000989 -0.034695 0.059537 0.064716 0.024870 -0.071974 -0.065573 0.004449 0.034669 0.052304 -0.061859 -0.007266 0.006972 0.093347 0.071865 -0.029031 -0.107339 0.024220 0.022169 -0.114337 -0.037606 -0.065620 0.020943 -0.010252 0.095278 0.066511 -0.076884 -0.062379 0.130051 0.217872 0.074797 -0.192851 -0.208987 -0.019366 -0.004054 0.092481 0.027660 -0.068540 0.024574 0.000841 0.230619 0.299878 0.037370 -0.328121 -0.072815 0.000255 0.075098 -0.006633 -0.021815 0.099009 -0.062379 0.152324 0.279559 0.054057 -0.284854 -0.094401 0.003794 0.048401 -0.017943 -0.018061 0.046883 0.037451 0.113447 0.067940 -0.061177 -0.139017 -0.068716 -0.009190 0.031352 -0.020749 -0.009630 0.047430 -0.001681 0.010137 -0.004260 0.077043 -0.095861 -0.101195 -0.017912 0.024507 -0.017393 -0.025043 0.052834 0.019087 0.054584 0.129125 0.125605 -0.180554 -0.035116 -0.022217 0.021044 0.018703 -0.039919 -0.002106 0.031998 0.050144 0.065709 -0.020840 -0.253646 0.016799 -0.021815 0.003010 0.026843 -0.003809 -0.044566 -0.041887 -0.032338 -0.049991 -0.040843 -0.059949 0.109206
3 11 11 2 2 0 0.227684 10.694053 -4.627366 11 11 5 -0.117889 0.135816 -0.028791 -0.000475 0.009764 0.038519 0.037895 -0.041032 -0.060443 -0.102676 -0.032585 -0.076413 0.035854 -0.002122 0.059548 0.059702 0.060483 0.034630 -0.014838 0.008385 0.002324 0.025943 -0.120792 0.063786 0.012966 0.073493 0.064465 0.002024 -0.005918 0.000408 -0.021241 0.005222 -0.053056 -0.100792 0.081468 0.032257 0.114852 0.059422 0.018532 -0.031277 0.006377 -0.063283 0.064405 -0.073981 -0.040957 0.098079 0.091958 0.125245 -0.050709 -0.037281 0.068618 0.164777 -0.016874 0.089605 -0.134759 0.024244 0.075618 0.035169 -0.034380 -0.202328 -0.164965 -0.028326 0.180086 0.104260 0.113024 -0.126890 0.031095 -0.009117 -0.089850 -0.134656 -0.025934 0.064213 -0.153699 -0.105035 0.042746 0.129590 -0.061212 -0.070266 0.009231 -0.080283 -0.055147 0.153817 0.073985 -0.278419 -0.183077 -0.031212 0.143118 -0.062538 -0.101937 -0.000147 -0.047495 0.056349 0.076247 -0.115479 -0.230186 -0.085269 -0.101444 0.134443 -0.070000 0.074030 0.044153 0.065562 0.105957 0.125087 0.134508 0.115299 0.101243 -0.053845 0.063417 -0.022346 0.060720 0.025339 0.052078 0.082144 0.095513 0.035344 -0.090609 -0.161260 -0.221464 0.070312 -0.017765
2 1 0.087818 7.093666 -4.471976 11 11 5 0.041797 -0.019372 0.009947 -0.005739 0.000883 -0.015793 -0.009506 0.007430 0.013298 0.083498 -0.089336 0.068233 -0.021882 -0.066813 -0.098548 -0.089879 -0.059714 -0.012765 0.000481 -0.003379 0.041683 -0.026343 0.051788 -0.075449 -0.141735 -0.147004 -0.070206 -0.014848 -0.011571 -0.026730 -0.042572 0.038325 0.014304 0.031923 -0.191573 -0.218342 -0.075410 0.009969 -0.042982 -0.118623 -0.075789 -0.002792 0.076073 0.068566 0.006329 -0.210209 -0.056043 0.114328 0.140044 0.085725 -0.035389 -0.123464 -0.176464 0.018250 0.075440 -0.064260 -0.138669 0.057490 0.154880 0.119030 0.036569 0.106692 0.097560 -0.196590 -0.148448 0.081064 -0.082858 -0.043613 0.038958 0.038552 -0.033534 0.018880 0.109049 0.159631 -0.003966 -0.178880 0.018485 -0.077671 -0.062470 -0.069398 -0.113431 -0.008140 0.186316 0.148600 0.088200 0.046706 -0.082834 0.028370 -0.021401 -0.071859 -0.106550 -0.067702 0.069044 0.222101 0.162533 0.056278 0.039800 -0.012078 -0.002865 0.105400 -0.007526 -0.042469 -0.043427 0.053027 0.153000 0.190787 0.127132 0.091602 0.104586 0.060299 -0.007574 -0.063439 -0.090103 -0.051046 0.007073 0.085089 0.141981 0.108941 0.016699 0.022813 -0.082466
3 11 11 2 2 0 0.227684 10.694053 -4.627366 11 11 5 0.060720 0.025339 0.052078 0.082144 0.095513 0.035344 -0.090609 -0.161260 -0.221464 0.070312 -0.017765 0.074030 0.044153 0.065562 0.105957 0.125087 0.134508 0.115299 0.101243 -0.053845 0.063417 -0.022346 -0.101937 -0.000147 -0.047495 0.056349 0.076247 -0.115479 -0.230186 -0.085269 -0.101444 0.134443 -0.070000 -0.070266 0.009231 -0.080283 -0.055147 0.153817 0.073985 -0.278419 -0.183077 -0.031212 0.143118 -0.062538 0.031095 -0.009117 -0.089850 -0.134656 -0.025934 0.064213 -0.153699 -0.105035 0.042746 0.129590 -0.061212 0.024244 0.075618 0.035169 -0.034380 -0.202328 -0.164965 -0.028326 0.180086 0.104260 0.113024 -0.126890 -0.040957 0.098079 0.091958 0.125245 -0.050709 -0.037281 0.068618 0.164777 -0.016874 0.089605 -0.134759 -0.100792 0.081468 0.032257 0.114852 0.059422 0.018532 -0.031277 0.006377 -0.063283 0.064405 -0.073981 -0.120792 0.063786 0.012966 0.073493 0.064465 0.002024 -0.005918 0.000408 -0.021241 0.005222 -0.053056 -0.076413 0.035854 -0.002122 0.059548 0.059702 0.060483 0.034630 -0.014838 0.008385 0.002324 0.025943 -0.117889 0.135816 -0.028791 -0.000475 0.009764 0.038519 0.037895 -0.041032 -0.060443 -0.102676 -0.032585
2 1 0.087818 7.093666 -4.471976 11 11 5 -0.007574 -0.063439 -0.090103 -0.051046 0.007073 0.085089 0.141981 0.108941 0.016699 0.022813 -0.082466 0.105400 -0.007526 -0.042469 -0.043427 0.053027 0.153000 0.190787 0.127132 0.091602 0.104586 0.060299 -0.021401 -0.071859 -0.106550 -0.067702 0.069044 0.222101 0.162533 0.056278 0.039800 -0.012078 -0.002865 -0.077671 -0.062470 -0.069398 -0.113431 -0.008140 0.186316 0.148600 0.088200 0.046706 -0.082834 0.028370 -0.082858 -0.043613 0.038958 0.038552 -0.033534 0.018880 0.109049 0.159631 -0.003966 -0.178880 0.018485 -0.064260 -0.138669 0.057490 0.154880 0.119030 0.036569 0.106692 0.097560 -0.196590 -0.148448 0.081064 0.006329 -0.210209 -0.056043 0.114328 0.140044 0.085725 -0.035389 -0.123464 -0.176464 0.018250 0.075440 0.031923 -0.191573 -0.218342 -0.075410 0.009969 -0.042982 -0.118623 -0.075789 -0.002792 0.076073 0.068566 0.051788 -0.075449 -0.141735 -0.147004 -0.070206 -0.014848 -0.011571 -0.026730 -0.042572 0.038325 0.014304 0.068233 -0.021882 -0.066813 -0.098548 -0.089879 -0.059714 -0.012765 0.000481 -0.003379 0.041683 -0.026343 0.041797 -0.019372 0.009947 -0.005739 0.000883 -0.015793 -0.009506 0.007430 0.013298 0.083498 -0.089336
3 11 11 2 2 0 0.251448 11.482649 -4.728630 11 11 5 -0.208246 0.141393 0.054024 0.131505 0.055476 -0.000286 -0.020794 0.093396 0.054185 0.082522 -0.156240 0.066468 0.029593 -0.051000 -0.017803 -0.058531 -0.009367 -0.053697 -0.014180 -0.005595 0.084328 0.011164 -0.056832 0.054761 -0.000896 -0.039453 -0.062555 0.029305 -0.027850 -0.040279 -0.028168 0.089666 -0.014193 -0.103775 0.004187 -0.073850 -0.039601 -0.045750 -0.001698 -0.164262 -0.212825 -0.110462 0.064595 0.034096 -0.041699 -0.030508 -0.027972 -0.008243 0.064087 0.104778 -0.014839 -0.091755 -0.146330 -0.040233 0.055593 0.090293 0.002192 0.096454 0.052004 0.115810 0.228014 0.163460 0.037982 -0.128981 -0.081961 0.061102 0.104292 0.031161 0.109489 0.083464 0.136726 0.274721 0.198272 0.038233 -0.136426 -0.110000 0.034320 -0.049266 -0.018135 -0.048695 -0.017758 0.036997 0.107383 -0.001687 -0.110363 -0.144870 -0.040065 0.093462 -0.117531 0.014004 -0.041742 -0.028877 0.005975 0.006102 -0.174966 -0.213354 -0.056458 0.056072 0.039924 0.009493 0.016181 -0.074724 -0.106150 -0.079796 0.006041 -0.029934 -0.102131 -0.058832 0.013034 0.032400 -0.125898 0.118649 0.092522 0.125605 0.001704 -0.037721 -0.022140 0.118391 0.096593 0.154463 -0.129879
2 1 0.089624 6.508753 -4.313786 11 11 5 0.034196 -0.043795 -0.026020 0.019666 0.053289 0.014761 -0.039266 -0.051510 -0.078378 -0.056550 0.048730 -0.045085 -0.091323 -0.050754 0.003498 -0.005652 -0.062395 -0.034208 0.019092 -0.003005 -0.091317 0.013820 -0.074209 -0.073332 -0.093164 -0.087009 -0.142222 -0.067517 0.051191 0.071375 0.088125 0.000752 0.006434 -0.063600 -0.076099 -0.108351 -0.114334 -0.151523 0.034752 0.140773 0.041890 0.032370 0.048614 -0.031557 0.056076 0.010162 -0.004115 -0.011253 -0.041250 0.113301 0.279557 0.183370 0.008265 0.036954 -0.000158 0.088173 0.047571 0.000092 -0.058135 -0.103911 -0.015999 0.220564 0.259383 0.004185 -0.004967 -0.003955 0.104124 0.046205 0.001144 -0.061424 -0.098231 -0.031496 0.221957 0.234496 -0.028055 -0.007062 -0.018070 0.032889 -0.009917 0.002242 -0.006743 -0.050737 0.099425 0.285633 0.165900 -0.012140 0.053170 0.000587 -0.067169 -0.114459 -0.140806 -0.124641 -0.123556 0.089634 0.172856 0.066046 0.023553 0.034883 -0.025916 -0.059806 -0.086152 -0.150894 -0.160164 -0.198911 -0.087654 0.044437 0.082365 0.087275 -0.044035 -0.016230 -0.001182 -0.016979 0.008162 0.048233 0.049917 -0.022982 -0.055056 -0.020174 -0.064098 -0.118971 0.043512
3 11 11 2 2 0 0.272854 11.199291 -4.815253 11 11 5 0.128172 0.075508 0.012087 -0.038017 0.054415 0.142637 0.072939 0.004925 -0.039050 -0.047771 -0.020268 0.012583 -0.071883 -0.077993 -0.025542 -0.003719 0.008771 0.026628 0.041655 0.004038 0.005318 -0.070196 -0.050349 -0.038426 0.002139 0.028158 -0.069437 -0.030019 0.044860 0.060299 -0.010421 0.023865 -0.066849 -0.139297 -0.000784 0.046867 -0.074412 -0.284563 -0.146464 0.012509 0.081202 -0.006611 0.018750 -0.079922 -0.014919 0.041502 0.128803 0.033268 -0.143849 -0.124793 -0.058101 0.093787 0.039027 0.006402 -0.074697 0.144627 0.033287 0.176607 0.200536 0.120389 -0.076716 -0.177442 0.053601 0.074737 0.010781 -0.037365 0.157991 0.037315 0.175683 0.201591 0.132046 -0.068183 -0.193648 0.043015 0.067376 -0.011658 -0.066997 0.010097 0.043279 0.134018 0.029142 -0.141104 -0.123671 -0.073665 0.082568 0.058668 0.012087 -0.053980 -0.101022 0.007362 0.079128 -0.056475 -0.284607 -0.151676 0.023659 0.102904 0.030064 0.008867 -0.050570 -0.122420 -0.095704 -0.019390 0.019177 -0.097685 -0.093969 -0.000395 0.037938 -0.005786 0.021683 -0.057717 0.163607 0.034992 -0.066557 -0.032896 0.088038 0.160342 0.137180 0.041430 -0.037716 -0.000199 -0.099362
2 1 0.111017 7.849043 -4.307929 11 11 5 0.010337 0.024505 0.048625 -0.062929 -0.095112 -0.081948 -0.061388 0.001006 0.020967 0.093301 -0.022171 -0.060763 -0.016614 -0.106560 -0.099112 0.007918 -0.003665 -0.155416 -0.116548 0.001837 0.054527 0.004977 -0.046983 -0.151967 -0.093400 0.044905 0.078053 0.090826 0.001538 -0.103595 0.002180 0.080123 0.017176 -0.071396 -0.225257 0.009595 0.165698 0.092580 0.002181 0.045379 -0.062916 -0.041797 0.067402 0.018647 0.050274 -0.156364 0.040882 0.215293 0.189215 0.031622 0.060893 -0.012004 -0.052590 0.085257 0.031421 0.023294 -0.156066 -0.049803 0.100584 0.194371 0.049644 0.016199 -0.011946 -0.101198 0.079590 0.016452 0.042525 -0.156854 -0.044643 0.094960 0.193979 0.036859 0.006671 -0.006688 -0.090549 0.092608 0.012100 0.033874 -0.159001 0.030132 0.204481 0.180655 0.008027 0.043271 -0.004746 -0.069695 0.107499 0.015248 -0.070450 -0.215547 0.066570 0.197687 0.111983 0.003685 0.056749 -0.057489 -0.026730 0.099795 0.010178 -0.089727 -0.245462 -0.163570 0.006348 0.059646 0.055266 -0.017139 -0.148469 -0.034372 0.053623 -0.010224 0.038280 0.031627 -0.016437 -0.089562 -0.039673 -0.040753 -0.102263 -0.056734 0.014017 0.095019 0.003648
3 11 11 2 2 0 0.216932 10.229708 -4.537143 11 11 5 0.007984 -0.056307 -0.072258 -0.037792 -0.033674 0.020447 -0.016370 0.007034 -0.094402 0.069451 -0.194260 0.066859 -0.017362 0.024123 -0.019607 -0.020265 0.026187 0.003528 -0.021853 -0.051447 0.040116 -0.024062 0.072121 -0.050823 0.047458 -0.021175 -0.017282 0.072902 0.101983 -0.003527 -0.069372 0.016186 -0.095454 0.188475 -0.045729 0.063901 -0.036621 -0.042199 0.083167 0.137606 0.043639 -0.048021 0.019739 -0.044477 0.194793 -0.108164 0.044456 -0.059966 0.016949 0.077034 0.012624 0.027507 -0.027191 0.038791 -0.031196 0.084004 -0.085498 0.047098 -0.028145 0.055613 -0.096301 -0.099457 0.164741 0.092667 0.023780 0.049082 0.038813 0.014236 0.037420 0.012250 0.088379 -0.332240 -0.303801 0.145681 0.160534 0.000189 0.105652 -0.022135 0.099542 0.037319 0.033636 0.134664 -0.205549 -0.316120 -0.047657 0.075213 -0.057263 0.124204 -0.117389 0.076441 0.047544 0.062582 0.006651 -0.042192 -0.079518 -0.090652 0.010956 -0.092733 0.093589 -0.127703 0.014724 0.005410 0.052663 -0.039161 -0.029269 0.013935 -0.039061 0.006959 -0.078032 0.020511 -0.032447 -0.047352 0.050667 0.076317 0.001487 -0.058290 -0.037488 0.113196 0.108637 -0.194898 0.149162
2 1 0.095330 7.005396 -4.249762 11 11 5 -0.028558 0.019011 -0.006088 -0.002289 -0.025953 -0.014510 -0.028750 -0.016074 -0.000094 0.076223 0.024005 0.003248 0.012214 0.025302 0.020217 -0.012372 -0.027400 -0.019027 0.005346 0.028130 0.068546 0.038248 -0.059514 -0.037567 0.022982 0.006638 -0.047383 -0.041319 -0.022699 0.004696 0.032580 0.050128 0.014409 -0.056397 -0.061141 0.016664 -0.023427 -0.105523 -0.020171 -0.012340 -0.005243 0.039689 0.031753 0.063952 -0.037363 -0.033189 0.020516 -0.109872 -0.179737 -0.036037 -0.011575 -0.191578 -0.073696 0.038641 0.056276 -0.031752 -0.039889 -0.051401 -0.150837 -0.015591 0.123860 0.248277 0.109920 -0.261578 -0.143149 0.035279 -0.007378 -0.035190 -0.181891 -0.088615 0.168114 0.121342 0.223154 0.269367 -0.042490 -0.251206 -0.071611 0.068056 -0.033291 -0.221603 -0.073262 0.216946 0.123573 0.090626 0.169845 -0.004981 -0.138529 -0.089077 0.038392 -0.015748 -0.197180 -0.082599 0.122420 0.131037 0.042565 0.044895 -0.036313 -0.075156 -0.067587 0.093152 0.064822 -0.041385 0.009384 0.143051 0.145821 0.094985 0.054098 0.025630 0.045027 0.022022 -0.005766 0.046406 -0.022736 0.000798 0.041665 -0.007101 0.013366 0.017274 -0.018359 0.008372 -0.042819
3 11 11 2 2 0 0.216932 10.229708 -4.537143 11 11 5 -0.032447 -0.047352 0.050667 0.076317 0.001487 -0.058290 -0.037488 0.113196 0.108637 -0.194898 0.149162 -0.127703 0.014724 0.005410 0.052663 -0.039161 -0.029269 0.013935 -0.039061 0.006959 -0.078032 0.020511 -0.117389 0.076441 0.047544 0.062582 0.006651 -0.042192 -0.079518 -0.090652 0.010956 -0.092733 0.093589 -0.022135 0.099542 0.037319 0.033636 0.134664 -0.205549 -0.316120 -0.047657 0.075213 -0.057263 0.124204 0.038813 0.014236 0.037420 0.012250 0.088379 -0.332240 -0.303801 0.145681 0.160534 0.000189 0.105652 0.084004 -0.085498 0.047098 -0.028145 0.055613 -0.096301 -0.099457 0.164741 0.092667 0.023780 0.049082 0.194793 -0.108164 0.044456 -0.059966 0.016949 0.077034 0.012624 0.027507 -0.027191 0.038791 -0.031196 0.188475 -0.045729 0.063901 -0.036621 -0.042199 0.083167 0.137606 0.043639 -0.048021 0.019739 -0.044477 0.072121 -0.050823 0.047458 -0.021175 -0.017282 0.072902 0.101983 -0.003527 -0.069372 0.016186 -0.095454 0.066859 -0.017362 0.024123 -0.019607 -0.020265 0.026187 0.003528 -0.021853 -0.051447 0.040116 -0.024062 0.007984 -0.056307 -0.072258 -0.037792 -0.033674 0.020447 -0.016370 0.007034 -0.094402 0.069451 -0.194260
2 1 0.095330 7.005396 -4.249762 11 11 5 -0.005766 0.046406 -0.022736 0.000798 0.041665 -0.007101 0.013366 0.017274 -0.018359 0.008372 -0.042819 0.093152 0.064822 -0.041385 0.009384 0.143051 0.145821 0.094985 0.054098 0.025630 0.045027 0.022022 0.038392 -0.015748 -0.197180 -0.082599 0.122420 0.131037 0.042565 0.044895 -0.036313 -0.075156 -0.067587 0.068056 -0.033291 -0.221603 -0.073262 0.216946 0.123573 0.090626 0.169845 -0.004981 -0.138529 -0.089077 -0.007378 -0.035190 -0.181891 -0.088615 0.168114 0.121342 0.223154 0.269367 -0.042490 -0.251206 -0.071611 -0.031752 -0.039889 -0.051401 -0.150837 -0.015591 0.123860 0.248277 0.109920 -0.261578 -0.143149 0.035279 -0.037363 -0.033189 0.020516 -0.109872 -0.179737 -0.036037 -0.011575 -0.191578 -0.073696 0.038641 0.056276 -0.056397 -0.061141 0.016664 -0.023427 -0.105523 -0.020171 -0.012340 -0.005243 0.039689 0.031753 0.063952 -0.059514 -0.037567 0.022982 0.006638 -0.047383 -0.041319 -0.022699 0.004696 0.032580 0.050128 0.014409 0.003248 0.012214 0.025302 0.020217 -0.012372 -0.027400 -0.019027 0.005346 0.028130 0.068546 0.038248 -0.028558 0.019011 -0.006088 -0.002289 -0.025953 -0.014510 -0.028750 -0.016074 -0.000094 0.076223 0.024005
3 11 11 2 2 0 0.162682 9.638678 -4.270794 11 11 5 0.071396 0.053744 0.107044 0.071349 -0.021030 -0.050268 -0.047529 -0.070487 -0.013731 -0.008373 0.158877 -0.108198 0.035189 0.029683 0.044855 0.026724 0.048524 -0.000474 -0.084088 -0.046448 -0.074585 0.034042 0.012010 -0.077508 -0.037894 0.044656 0.055505 0.007913 -0.025823 -0.049752 -0.008778 -0.076355 0.076269 0.000762 -0.221397 -0.061478 -0.034365 0.114945 0.012366 -0.082097 -0.043443 0.025049 -0.036035 -0.006039 0.112748 -0.159701 0.042560 -0.025827 0.169325 0.116039 -0.160968 -0.065985 0.095482 0.069776 -0.014415 0.256648 -0.122070 0.005385 -0.137385 -0.044356 0.200629 -0.038427 -0.103497 0.026643 0.057454 -0.057768 0.282324 -0.107863 0.016290 -0.125561 -0.041771 0.193368 -0.024272 -0.108900 0.021002 0.068081 -0.045543 0.103102 -0.187503 -0.006119 -0.041168 0.168713 0.115370 -0.130869 -0.068243 0.110163 0.063410 -0.018800 0.019644 -0.165692 -0.041363 -0.031246 0.131734 0.017016 -0.098204 -0.075021 -0.001712 -0.034534 0.039828 -0.057288 -0.150394 -0.069825 -0.013365 0.052527 0.041940 0.018703 -0.024979 0.029388 -0.065924 0.009233 0.029744 0.097613 0.152998 0.111702 0.018561 -0.009899 -0.033835 -0.140346 -0.060576 -0.077038 0.178386
2 1 0.065672 6.714428 -4.077400 11 11 5 -0.058165 -0.061465 -0.074613 -0.111231 -0.046340 -0.002688 0.051902 0.078688 0.061761 -0.048143 -0.037283 -0.094390 0.018525 -0.058747 -0.288255 -0.248635 0.000767 0.087466 0.048975 0.022350 -0.029887 -0.090596 -0.020297 0.153144 0.124388 -0.110967 -0.228288 0.057423 0.106198 0.053379 0.051760 -0.013411 -0.034495 0.021334 0.123008 0.064834 -0.047629 -0.189709 0.059383 0.063072 0.014434 0.064126 -0.009635 0.003442 0.054471 0.132272 0.086410 0.036461 -0.138523 0.103784 0.116771 0.012284 0.049637 -0.006121 0.007779 0.015200 0.111605 0.046494 0.011841 -0.219207 -0.008632 0.104540 -0.032276 -0.017536 -0.043056 -0.003107 0.023316 0.137801 0.045356 0.042087 -0.197436 -0.019573 0.107560 -0.036442 -0.006536 -0.048954 0.007805 0.033395 0.120696 0.039793 0.052686 -0.113412 0.087574 0.110936 -0.015941 0.042619 -0.049747 0.016729 0.046318 0.121400 0.041108 -0.017075 -0.147210 0.081875 0.093490 0.027634 0.090392 -0.027887 0.012320 -0.018981 0.114595 0.028815 -0.185653 -0.278599 0.027970 0.067476 0.009155 0.048005 -0.017922 -0.051151 -0.088043 -0.009343 -0.064033 -0.181957 -0.146376 0.057815 0.103691 0.030106 0.066251 0.017236 -0.078316
3 11 11 2 2 0 0.177400 8.831716 -4.251668 11 11 5 0.114874 0.080859 0.068775 -0.041075 -0.061545 -0.056367 -0.094200 -0.024463 0.085384 0.104677 0.017028 -0.004300 0.054934 0.039597 0.059215 0.048601 -0.049895 -0.113990 -0.077016 -0.015051 -0.018288 0.077754 -0.111301 0.033747 -0.001164 0.070318 -0.008869 -0.053711 -0.039486 -0.067163 0.011886 -0.015386 0.089793 -0.177996 -0.048096 0.002481 0.150800 -0.044086 -0.130883 -0.007297 0.002328 -0.007702 -0.076222 0.054926 -0.035200 -0.046238 0.053572 0.189747 0.015004 -0.177423 0.008029 0.190836 0.039119 -0.079979 0.048778 0.095240 -0.117231 -0.062004 0.045461 0.171691 -0.129275 -0.108250 0.167577 -0.008041 -0.151160 0.040751 0.118383 -0.128596 -0.070093 0.047993 0.175418 -0.137171 -0.110031 0.177041 0.006016 -0.141626 0.059282 -0.031774 -0.096474 0.041652 0.190558 0.032009 -0.169549 0.020384 0.195316 0.025454 -0.092491 0.041827 -0.105495 -0.046517 0.033431 0.132075 -0.047173 -0.142024 -0.041599 -0.007023 -0.004205 -0.019599 0.073835 -0.193699 -0.052779 0.004851 0.071738 0.042036 -0.025972 -0.006542 -0.036868 -0.025046 -0.039356 0.046603 0.140143 0.150332 0.076637 0.017081 0.030988 -0.110084 -0.178251 -0.092514 0.050423 0.058058 0.119557
2 1 0.062338 6.398349 -4.061878 11 11 5 -0.162747 -0.033055 -0.123484 -0.049985 0.053292 0.078144 0.096235 0.064622 -0.041064 -0.145023 0.040162 -0.019429 -0.066687 -0.314277 -0.126258 0.091530 0.074741 0.059599 0.057588 -0.016434 -0.157443 -0.121322 0.052511 0.123868 -0.209346 -0.099589 0.146339 0.066968 0.038856 0.060337 -0.007544 -0.069974 -0.032667 0.034017 0.129384 -0.153050 -0.095888 0.143865 0.022880 0.035871 0.086463 0.013154 -0.047249 -0.002862 0.037759 0.147045 -0.059086 -0.052133 0.169781 0.046951 0.007138 0.080431 0.006919 -0.019275 0.023684 0.022360 0.122597 -0.075539 -0.138827 0.096523 0.022774 -0.040715 0.008303 -0.032271 -0.009436 0.010375 0.020878 0.146279 -0.044474 -0.120438 0.107576 0.031135 -0.020147 0.002070 -0.046772 -0.006407 0.010198 0.040927 0.127222 -0.057765 -0.061845 0.136587 0.036406 0.021361 0.048271 -0.024664 -0.001423 -0.005640 0.024441 0.106974 -0.094958 -0.070281 0.163160 0.040631 0.044907 0.091863 0.001814 -0.015239 0.011481 0.038679 0.046456 -0.254117 -0.139203 0.137663 0.046198 0.007772 0.047826 -0.012251 -0.069127 -0.086885 -0.094314 -0.014379 -0.223694 -0.072694 0.115262 0.068250 0.068804 0.101701 -0.008371 -0.158663 -0.039449
3 11 11 2 2 0 0.169456 9.911836 -4.291732 11 11 5 0.158688 0.030913 -0.006532 -0.139598 -0.097854 -0.012942 0.052740 0.096051 0.086746 0.100998 -0.171936 0.035368 0.052434 0.023515 0.082111 -0.043630 -0.171501 -0.115333 -0.030094 0.038444 0.015230 0.130258 -0.101065 0.065132 -0.047573 0.076070 -0.040636 -0.099819 -0.031939 -0.032871 0.048702 0.012369 0.039604 -0.153767 0.079751 0.016751 0.044900 -0.111367 -0.092192 0.034009 -0.020237 -0.036063 -0.044122 0.104640 -0.094192 0.067728 0.063230 0.098161 -0.032884 -0.070922 0.115817 0.110000 -0.055458 -0.119993 0.142955 -0.032548 0.004724 -0.020059 0.076472 0.059463 -0.136980 0.012743 0.126571 -0.126871 -0.193271 0.153556 -0.003127 -0.012482 -0.038750 0.031485 0.062714 -0.146413 0.025663 0.156625 -0.122266 -0.153345 0.169890 -0.093873 0.030885 0.077510 0.106454 0.020027 -0.071595 0.104334 0.096931 -0.100399 -0.106021 0.137936 -0.127492 0.064717 -0.012422 0.019248 -0.113235 -0.120260 0.032762 0.026143 0.012664 -0.015680 0.079411 -0.160850 0.057721 -0.003807 0.136787 0.007879 -0.085394 -0.051203 -0.057628 -0.016007 -0.016791 0.089663 0.167627 0.112619 -0.010746 -0.021263 -0.150801 -0.172972 -0.059888 0.043756 0.127057 0.142517 -0.068912
2 1 0.059222 5.683235 -4.082650 11 11 5 -0.200205 -0.030632 -0.041267 0.036899 0.087234 0.096400 0.088400 -0.067165 -0.179999 -0.137655 0.120376 -0.049095 -0.147806 -0.156191 0.101801 0.163960 0.049827 0.044435 -0.000476 -0.107999 -0.304387 -0.098573 0.028575 -0.099244 -0.127946 0.144918 0.159858 -0.007827 0.001035 -0.013161 -0.008369 -0.071151 -0.059700 0.039741 -0.024674 -0.089251 0.160643 0.157937 0.019797 0.038278 -0.043175 -0.015574 0.015488 -0.047439 0.064603 0.042827 -0.048552 0.150131 0.139198 0.044071 0.043425 -0.074507 -0.008959 0.066942 -0.008103 0.043308 0.040252 -0.088367 0.060803 0.052943 0.005236 -0.014404 -0.117714 -0.022998 0.072130 -0.006623 0.055084 0.057142 -0.088687 0.057127 0.053782 0.001120 0.002101 -0.115416 -0.025290 0.088134 0.011297 0.048446 0.040161 -0.047789 0.113835 0.137215 0.034603 0.041859 -0.080491 -0.018611 0.064587 -0.029081 0.017571 0.011320 -0.047202 0.115965 0.144845 0.028382 0.035834 -0.034289 -0.031797 0.042923 -0.003965 0.017706 -0.094289 -0.111701 0.110664 0.149856 0.000963 -0.008365 -0.011780 -0.037067 -0.146982 -0.145116 -0.140953 -0.096771 -0.082469 0.140736 0.150326 0.039897 0.049483 -0.009572 -0.134230 -0.247171 0.063840
3 11 11 2 2 0 0.152212 9.383471 -4.329970 11 11 5 0.149392 -0.178890 -0.039735 -0.024301 0.062102 0.123687 0.107406 0.084800 -0.084664 0.130536 -0.366958 0.076060 0.049202 -0.082711 -0.197450 -0.158190 -0.028006 0.053900 0.054177 0.024371 0.042925 0.128143 -0.031503 0.066023 -0.069794 -0.061080 -0.054986 0.032005 0.037766 0.004933 0.001508 0.094006 -0.084300 -0.008741 0.028146 -0.092726 -0.071409 -0.016192 -0.034956 -0.056757 0.000637 0.016199 0.090128 0.007376 0.057895 0.057483 -0.025992 -0.006941 0.128164 0.024018 -0.112559 0.009368 0.004135 0.100898 0.028348 -0.029066 0.048052 0.021333 -0.118333 0.092770 0.056134 -0.214144 -0.061286 0.005874 0.122895 0.059992 -0.047206 0.047807 0.002806 -0.095328 0.099600 0.079111 -0.199159 -0.031130 0.037668 0.088718 0.028453 0.007549 0.096318 0.001931 -0.005667 0.089915 0.014080 -0.143946 -0.009072 0.023433 0.088477 0.079687 -0.052205 0.005334 -0.117674 -0.051782 -0.003408 0.014445 0.017345 0.014079 0.038499 0.065362 -0.058180 0.013202 0.123153 -0.010159 -0.082239 -0.128545 -0.049890 0.006855 -0.015885 0.010663 0.069538 0.065332 0.161071 -0.085455 -0.140914 -0.182392 -0.045321 0.081473 0.141032 0.135955 -0.008965 0.114702 -0.270184
2 1 0.063275 6.164028 -4.220882 11 11 5 -0.100588 -0.011280 0.054758 0.108284 0.052202 -0.113393 -0.248927 -0.129176 0.013023 0.109309 0.104236 -0.060764 0.113729 0.147417 0.080519 0.073569 0.041359 -0.128089 -0.280080 -0.175176 -0.014113 0.013659 -0.083687 0.092359 0.105904 -0.026662 -0.012203 -0.027329 0.003206 -0.012278 -0.150641 -0.055418 0.008568 -0.010064 0.117581 0.143726 0.019967 0.033374 -0.011289 0.021809 0.062585 -0.060735 -0.117222 -0.007388 0.043426 0.098307 0.132158 0.046691 0.008633 -0.029818 0.016603 0.099570 0.033989 -0.139443 -0.019666 0.035948 0.050709 0.074488 0.017379 -0.049412 -0.060801 0.012546 0.118107 0.060787 -0.173188 -0.087162 0.028510 0.020873 0.067519 0.023420 -0.058088 -0.061101 0.006459 0.124268 0.072213 -0.146937 -0.085438 0.050202 0.077806 0.139418 0.065722 0.003287 -0.005421 0.028162 0.094452 0.025017 -0.147583 -0.044762 -0.013462 0.077691 0.108387 0.016362 0.002784 -0.002028 -0.006704 0.075055 -0.016269 -0.114192 0.016249 -0.026081 0.106886 0.156248 0.009333 0.006200 0.031822 0.006889 -0.105461 -0.220057 -0.126232 -0.042307 -0.124220 0.065156 0.098977 0.056426 0.045874 -0.052994 -0.195531 -0.218417 -0.076007 0.095264 0.111865
3 11 11 2 2 0 0.148206 7.630037 -4.517362 11 11 5 0.064344 -0.001848 -0.024867 -0.120910 -0.259723 -0.209417 0.019981 0.030101 0.049333 -0.007950 0.102265 0.012195 0.059257 0.123385 0.184865 0.080585 -0.033668 -0.026718 -0.042442 0.020598 -0.052875 0.025651 -0.061530 0.079772 0.014793 0.052192 0.002901 -0.111078 -0.105961 -0.058619 0.024271 -0.027838 0.048995 -0.118123 0.121709 0.037042 0.111544 0.122918 -0.022082 -0.111949 -0.069283 0.007278 -0.035122 0.014098 -0.152779 0.162650 0.034227 0.072969 0.093402 0.002037 -0.101023 -0.071777 0.037750 0.029392 0.017937 -0.175384 0.176188 0.046809 0.028561 0.050931 0.037123 -0.163024 -0.170725 0.018246 0.000972 -0.011931 -0.168718 0.145163 0.034488 0.003181 0.044861 0.064833 -0.118621 -0.118146 0.057387 0.041271 0.016330 -0.166177 0.134861 0.093858 0.100347 0.114441 0.050018 -0.085623 -0.052457 0.071906 0.031681 -0.003660 -0.064032 0.123368 0.054553 0.033662 -0.002614 -0.094136 -0.158006 -0.077380 0.047408 -0.020243 0.019460 -0.019131 0.048052 0.015893 0.142823 0.156649 0.026724 -0.103176 -0.093706 0.043815 -0.052128 0.000057 0.033163 0.077800 0.024279 0.013616 -0.201747 -0.253778 -0.040441 0.009225 0.046066 -0.024229 0.126285
2 1 0.071109 4.743382 -4.024578 11 11 5 -0.226850 -0.028885 0.055025 0.164428 0.079766 -0.067444 -0.082425 -0.035814 -0.028574 -0.003998 -0.009811 -0.100687 -0.087684 -0.054264 0.064707 0.152574 0.096503 0.013468 0.016103 0.043046 0.045917 0.016311 -0.025259 -0.135995 -0.109879 0.018760 0.152500 0.120232 0.000272 -0.034368 0.020488 -0.010323 -0.022960 0.041356 -0.070673 -0.189293 -0.016957 0.141072 0.174062 0.055301 -0.051243 0.030171 -0.007954 -0.035300 0.080348 0.013870 -0.188168 -0.089841 0.067151 0.165541 0.076672 -0.071555 0.024590 -0.014600 -0.045647 0.074328 -0.000062 -0.176316 -0.129953 0.012779 0.175245 0.103551 -0.037695 -0.006401 -0.032913 -0.014421 0.076804 -0.011579 -0.183963 -0.124387 0.037320 0.172791 0.087907 -0.024558 -0.007919 -0.040664 -0.010257 0.085526 -0.008604 -0.192208 -0.079842 0.077647 0.188216 0.077972 -0.030051 -0.003936 -0.017580 -0.030103 0.044527 -0.076473 -0.132079 0.015811 0.110725 0.135782 0.023817 -0.030532 -0.014922 0.006225 -0.039602 0.004368 -0.136972 -0.109110 0.018061 0.120827 0.124041 0.053862 0.002231 -0.004471 0.028575 0.008073 -0.275841 -0.102768 0.010611 0.147700 0.153200 0.002833 -0.082784 -0.088909 -0.024701 0.019406 -0.001969

Some files were not shown because too many files have changed in this diff Show More