-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathpdb.m
55 lines (48 loc) · 1.54 KB
/
pdb.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
% the input are all the facial landmarks in a 2L*N matrix
% the output is the re-balanced index for PDB
% to test this code run
% load ./data/aflwTrainData.mat
% allShapes = [];
% for i = 1:20000
% allShapes(:,i) = trainData(i).gtLmk;
% end
% pdbIdx = pdb(allShapes, 9);
function newIdx = pdb(allShapes, numBins)
% align all the facial landmark using procrustes analysis
alignedShape = allShapes;
meanShape = mean(alignedShape, 2);
for i = 1:length(alignedShape)
[~, tmpS] = procrustes(reshape(meanShape,[],2), reshape(alignedShape(:,i),[],2));
alignedShape(:,i) = [tmpS(:,1); tmpS(:,2)];
end
% apply pca to aligned shapes
meanShape = mean(alignedShape,2);
[COEFF,~,~] = pca(alignedShape');
% select the shape eigen vector controlling pose variations
numLmk = size(allShapes, 1) / 2;
switch numLmk
case 19
poseEig = COEFF(:, 2);
otherwise
poseEig = COEFF(:, 1);
end
posePara = poseEig' * (alignedShape - repmat(meanShape, 1, length(alignedShape)));
% balance the training samples by yaw rotations
absPosePara = abs(posePara);
maxPasePara = max(absPosePara);
maxSampleInBins = max(hist(absPosePara, numBins));
newIdx = [];
for i = 1:numBins
tmp1 = find(absPosePara >= (i-1)*maxPasePara/numBins);
tmp2 = find(absPosePara <= i*maxPasePara/numBins);
tmpTrainIdx = intersect(tmp1, tmp2);
ratio = round(maxSampleInBins / length(tmpTrainIdx));
newIdx = [newIdx, repmat(tmpTrainIdx, 1, ratio)];
end
%% debug
% figure();
% subplot(1,2,1);
% hist(absPosePara, numBins);
% subplot(1,2,2);
% hist(absPosePara(newIdx), numBins);
end