001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.demos; 031 032import java.io.File; 033import java.io.IOException; 034import java.util.ArrayList; 035import java.util.Collections; 036import java.util.List; 037 038import org.openimaj.feature.local.list.MemoryLocalFeatureList; 039import org.openimaj.image.feature.dense.gradient.dsift.FloatDSIFTKeypoint; 040import org.openimaj.io.IOUtils; 041import org.openimaj.math.matrix.algorithm.pca.ThinSvdPrincipalComponentAnalysis; 042import org.openimaj.util.array.ArrayUtils; 043import org.openimaj.util.function.Operation; 044import org.openimaj.util.parallel.Parallel; 045 046import scala.actors.threadpool.Arrays; 047import Jama.Matrix; 048 049public class FVFWDSiftPCAAugment { 050 static Matrix sample(File dir, int nsamples) throws IOException { 051 final List<File> files = new ArrayList<File>(); 052 053 System.out.println("Finding files"); 054 for (final File d : dir.listFiles()) { 055 if (d.isDirectory()) { 056 for (final File f : d.listFiles()) { 057 if (f.getName().endsWith(".bin")) { 058 files.add(f); 059 } 060 } 061 } 062 } 063 064 System.out.println("Shuffling"); 065 Collections.shuffle(files); 066 067 System.out.println("Sampling"); 068 final double[][] data = new double[nsamples][]; 069 final int nPerFile = (int) Math.ceil(nsamples / (double) files.size()); 070 final List<FloatDSIFTKeypoint> samples = new ArrayList<FloatDSIFTKeypoint>(); 071 072 Parallel.forEach(files, new Operation<File>() { 073 @Override 074 public void perform(File f) { 075 try { 076 System.out.println(f); 077 078 final MemoryLocalFeatureList<FloatDSIFTKeypoint> feats = MemoryLocalFeatureList.read(f, 079 FloatDSIFTKeypoint.class); 080 081 Collections.shuffle(feats); 082 083 final MemoryLocalFeatureList<FloatDSIFTKeypoint> s = feats.subList(0, nPerFile); 084 synchronized (samples) { 085 samples.addAll(s); 086 } 087 } catch (final Exception e) { 088 e.printStackTrace(); 089 } 090 } 091 }); 092 093 for (int i = 0; i < nsamples; i++) { 094 data[i] = ArrayUtils.convertToDouble(samples.get(i).descriptor); 095 } 096 097 System.out.println("Done"); 098 099 return new Matrix(data); 100 } 101 102 @SuppressWarnings("unchecked") 103 private static void processFiles(final ThinSvdPrincipalComponentAnalysis pca, final File indir, final File outdir) 104 throws IOException 105 { 106 for (final File d : indir.listFiles()) { 107 if (d.isDirectory()) { 108 109 Parallel.forEach(Arrays.asList(d.listFiles()), new Operation<File>() { 110 @Override 111 public void perform(File f) { 112 final Matrix basis = pca.getBasis(); 113 final Matrix tmp = new Matrix(1, 128); 114 if (f.getName().endsWith(".bin")) { 115 try { 116 System.out.println("Processing " + f); 117 118 final MemoryLocalFeatureList<FloatDSIFTKeypoint> feats = MemoryLocalFeatureList.read(f, 119 FloatDSIFTKeypoint.class); 120 121 final File outfile = new File(outdir, f.getAbsolutePath().replace( 122 indir.getAbsolutePath(), "")); 123 outfile.getParentFile().mkdirs(); 124 125 for (final FloatDSIFTKeypoint kpt : feats) { 126 tmp.getArray()[0] = ArrayUtils.convertToDouble(kpt.descriptor); 127 final double[] proj = tmp.times(basis).getArray()[0]; 128 kpt.descriptor = ArrayUtils.convertToFloat(proj); 129 130 kpt.descriptor = Arrays.copyOf(kpt.descriptor, kpt.descriptor.length + 2); 131 kpt.descriptor[kpt.descriptor.length - 2] = (kpt.x / 125f) - 0.5f; 132 kpt.descriptor[kpt.descriptor.length - 1] = (kpt.y / 160f) - 0.5f; 133 } 134 135 IOUtils.writeBinary(outfile, feats); 136 f.delete(); 137 } catch (final Exception e) { 138 139 } 140 } 141 } 142 }); 143 } 144 } 145 } 146 147 /** 148 * @param args 149 * @throws IOException 150 */ 151 public static void main(String[] args) throws IOException { 152 final File indir = new File("/Volumes/Raid/face_databases/lfw-centre-affine-pdsift/"); 153 final Matrix samples = sample(indir, 100000); 154 155 final ThinSvdPrincipalComponentAnalysis pca = new 156 ThinSvdPrincipalComponentAnalysis(64); 157 System.out.println("Performing PCA"); 158 pca.learnBasis(samples); 159 IOUtils.writeToFile(pca, new 160 File("/Volumes/Raid/face_databases/lfw-centre-affine-pdsift-pca64.bin")); 161 // final ThinSvdPrincipalComponentAnalysis pca = 162 // IOUtils.readFromFile(new File( 163 // "/Volumes/Raid/face_databases/lfw-centre-affine-pdsift-pca64.bin")); 164 165 processFiles(pca, indir, new File("/Volumes/Raid/face_databases/lfw-centre-affine-pdsift-pca64" + 166 "/")); 167 } 168}