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 package org.openimaj.demos;
31
32 import java.io.File;
33 import java.io.IOException;
34
35 import org.openimaj.demos.FVFWDSift.DSFactory;
36 import org.openimaj.feature.FloatFV;
37 import org.openimaj.feature.local.list.LocalFeatureList;
38 import org.openimaj.feature.local.list.MemoryLocalFeatureList;
39 import org.openimaj.image.FImage;
40 import org.openimaj.image.ImageUtilities;
41 import org.openimaj.image.analysis.pyramid.SimplePyramid;
42 import org.openimaj.image.feature.dense.gradient.dsift.ApproximateDenseSIFT;
43 import org.openimaj.image.feature.dense.gradient.dsift.ByteDSIFTKeypoint;
44 import org.openimaj.image.feature.dense.gradient.dsift.DenseSIFT;
45 import org.openimaj.image.feature.dense.gradient.dsift.FloatDSIFTKeypoint;
46 import org.openimaj.image.feature.local.aggregate.FisherVector;
47 import org.openimaj.io.IOUtils;
48 import org.openimaj.math.matrix.algorithm.pca.PrincipalComponentAnalysis;
49 import org.openimaj.math.statistics.distribution.MixtureOfGaussians;
50 import org.openimaj.util.array.ArrayUtils;
51 import org.openimaj.util.function.Operation;
52 import org.openimaj.util.parallel.Parallel;
53
54 import scala.actors.threadpool.Arrays;
55
56 public class FVFWFVEncodeMatlab {
57
58
59
60
61 @SuppressWarnings("unchecked")
62 public static void main(String[] args) throws IOException {
63 final MixtureOfGaussians gmm = FVFWCheckPCAGMM.loadMoG(new File(
64 "/Users/jon/Downloads/data/lfw_aligned/SIFT_1pix_PCA64_GMM512/codebooks/1/gmm_512.mat"));
65 final PrincipalComponentAnalysis pca = FVFWCheckPCAGMM.loadPCA(new File(
66 "/Users/jon/Downloads/data/lfw_aligned/SIFT_1pix_PCA64_GMM512/codebooks/1/PCA_64.mat"));
67
68 final FisherVector<float[]> fisher = new FisherVector<float[]>(gmm, true, true);
69
70 final DSFactory factory = new DSFactory() {
71 @Override
72 public DenseSIFT create() {
73 return new ApproximateDenseSIFT(1, 6);
74 }
75 };
76
77 final File indir = new File("/Volumes/Raid/face_databases/lfw-centre-affine-matlab/");
78 final File outdir = new File("/Volumes/Raid/face_databases/lfw-centre-affine-matlab-fisher/");
79
80 Parallel.forEach(Arrays.asList(indir.listFiles()), new Operation<File>() {
81 @Override
82 public void perform(File dir) {
83 if (dir.isDirectory()) {
84 final DenseSIFT sift = factory.create();
85
86 for (final File f : dir.listFiles()) {
87 if (f.getName().endsWith(".jpg")) {
88 try {
89 final File outfile = new File(outdir, f.getAbsolutePath().replace(
90 indir.getAbsolutePath(), "").replace(".jpg", ".bin"));
91 outfile.getParentFile().mkdirs();
92
93 if (outfile.exists())
94 continue;
95
96 System.out.println(f);
97
98 final LocalFeatureList<FloatDSIFTKeypoint> features = computeFeatures(f, pca, sift);
99
100 final FloatFV fv = fisher.aggregate(features);
101 IOUtils.writeBinary(outfile, fv);
102 } catch (final Exception e) {
103 e.printStackTrace();
104 }
105 }
106 }
107 }
108 }
109
110 private LocalFeatureList<FloatDSIFTKeypoint> computeFeatures(File f, PrincipalComponentAnalysis pca,
111 DenseSIFT sift) throws IOException
112 {
113 final FImage image = ImageUtilities.readF(f);
114
115 final SimplePyramid<FImage> pyr = new SimplePyramid<FImage>((float) Math.sqrt(2), 5);
116 pyr.processImage(image);
117
118 final LocalFeatureList<FloatDSIFTKeypoint> allKeys = new MemoryLocalFeatureList<FloatDSIFTKeypoint>();
119 for (final FImage img : pyr) {
120 sift.analyseImage(img);
121
122 final double scale = 160.0 / img.height;
123 final LocalFeatureList<ByteDSIFTKeypoint> kps = sift.getByteKeypoints();
124 for (final ByteDSIFTKeypoint kp : kps) {
125 kp.x = (float) ((kp.x + 1) * scale);
126 kp.y = (float) ((kp.y + 1) * scale);
127
128 float[] descriptor = new float[128];
129 float sumsq = 0;
130
131
132
133 for (int i = 0; i < 16; i++) {
134 descriptor[i * 8] = kp.descriptor[i * 8] + 128;
135 descriptor[i * 8 + 1] = kp.descriptor[i * 8 + 7] + 128;
136 descriptor[i * 8 + 2] = kp.descriptor[i * 8 + 6] + 128;
137 descriptor[i * 8 + 3] = kp.descriptor[i * 8 + 5] + 128;
138 descriptor[i * 8 + 4] = kp.descriptor[i * 8 + 4] + 128;
139 descriptor[i * 8 + 5] = kp.descriptor[i * 8 + 3] + 128;
140 descriptor[i * 8 + 6] = kp.descriptor[i * 8 + 2] + 128;
141 descriptor[i * 8 + 7] = kp.descriptor[i * 8 + 1] + 128;
142 }
143
144 for (int i = 0; i < 128; i++) {
145 descriptor[i] = (float) Math.sqrt(descriptor[i]);
146 sumsq += descriptor[i] * descriptor[i];
147 }
148 sumsq = (float) Math.sqrt(sumsq);
149 final float norm = 1f / Math.max(Float.MIN_NORMAL, sumsq);
150 for (int i = 0; i < 128; i++) {
151 descriptor[i] *= norm;
152 }
153
154
155 descriptor = ArrayUtils.convertToFloat(pca.project(ArrayUtils.convertToDouble(descriptor)));
156
157
158 final int nf = descriptor.length;
159 descriptor = Arrays.copyOf(descriptor, nf + 2);
160 descriptor[nf] = (kp.x / 125f) - 0.5f;
161 descriptor[nf + 1] = (kp.y / 160f) - 0.5f;
162
163 allKeys.add(new FloatDSIFTKeypoint(kp.x, kp.y, descriptor, kp.energy));
164 }
165 }
166 return allKeys;
167 }
168
169 });
170
171 FVFWExperiment.main(null);
172 }
173 }