GroundTruthReader.java

package ac.essex.ooechs.imaging.commons.cmu; 
 
import ac.essex.ooechs.imaging.commons.Pixel; 
 
import java.util.Vector; 
import java.util.StringTokenizer; 
import java.util.Hashtable; 
import java.io.File; 
import java.io.IOException; 
import java.io.BufferedReader; 
import java.io.FileReader; 
 
/** 
 * <p/> 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 
 * of the License, or (at your option) any later version, 
 * provided that any use properly credits the author. 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details at http://www.gnu.org 
 * </p> 
 * 
 * @author Olly Oechsle, University of Essex, Date: 29-Sep-2006 
 * @version 1.0 
 */ 
public class GroundTruthReader { 
 
    public static void main(String[] args) { 
        File f = new File("/home/ooechs/ecj-training/faces/mit+cmu/truth.txt"); 
        if (!f.exists()) { 
            System.err.println("File does not exist: " + f.getAbsolutePath()); 
        } else { 
            new GroundTruthReader(f); 
        } 
    } 
 
    Hashtable<String, Vector<FaceDefinition>> faces; 
 
    /** 
     * Initialises the GroundTruthReader with a file containing Ground Truth Data 
     * in the format used in the MIT+CMU training set, a link to which is: 
     * <a href="http://vasc.ri.cmu.edu/idb/images/face/frontal_images/list.html">here</a> 
     * @param f The file to read the data from 
     */ 
    public GroundTruthReader(File f) { 
        faces = read(f); 
    } 
 
    /** 
     * Returns all the face definitions, ordered per filename. This is implemented 
     * as a hashtable using the filenames as keys, storing Vectors of Face Definition 
     * objects. 
     */ 
    public Hashtable<String, Vector<FaceDefinition>> getFaces() { 
        return faces; 
    } 
 
    /** 
     * Returns the faces to be found in a particular filename. Returned as a 
     * Vector of Face Definition Objects. 
     * @return A Vector, or null if no matches found. 
     */ 
    public Vector<FaceDefinition> getFaces(String imageName) { 
        return faces.get(imageName); 
    } 
 
    /** 
     * Reads the file and creates the hashtable 
     */ 
    private Hashtable<String, Vector<FaceDefinition>> read(File f) { 
 
        String line; 
 
        Hashtable<String, Vector<FaceDefinition>> hashtable = new Hashtable<String, Vector<FaceDefinition>>(130); 
 
        try { 
 
            BufferedReader in = new BufferedReader(new FileReader(f)); 
 
            if (!in.ready()) throw new IOException(); 
 
            while ((line = in.readLine()) != null) { 
 
                // ignore blank lines 
                if (line.trim().length() == 0 || line.startsWith("#")) continue; 
 
                // split up the line 
                StringTokenizer tokeniser = new StringTokenizer(line); 
 
                if (tokeniser.countTokens() == 13) { 
 
                    String filename = tokeniser.nextToken(); 
                    int leftEyeX = doubleToString(tokeniser.nextToken()); 
                    int leftEyeY = doubleToString(tokeniser.nextToken()); 
                    int rightEyeX = doubleToString(tokeniser.nextToken()); 
                    int rightEyeY = doubleToString(tokeniser.nextToken()); 
                    int noseX = doubleToString(tokeniser.nextToken()); 
                    int noseY = doubleToString(tokeniser.nextToken()); 
                    int leftCornerMouthX = doubleToString(tokeniser.nextToken()); 
                    int leftCornerMouthY = doubleToString(tokeniser.nextToken()); 
                    int centerMouthX = doubleToString(tokeniser.nextToken()); 
                    int centerMouthY = doubleToString(tokeniser.nextToken()); 
                    int rightCornerMouthX = doubleToString(tokeniser.nextToken()); 
                    int rightCornerMouthY = doubleToString(tokeniser.nextToken()); 
 
                    FaceDefinition face = new FaceDefinition(filename, new Pixel(leftEyeX, leftEyeY), new Pixel(rightEyeX, rightEyeY), new Pixel(noseX, noseY), new Pixel(leftCornerMouthX, leftCornerMouthY), new Pixel(centerMouthX, centerMouthY), new Pixel(rightCornerMouthX, rightCornerMouthY)); 
 
                    // see if already in our hashtable list 
                    Vector<FaceDefinition> facesOnImage = hashtable.get(filename); 
                    if (facesOnImage == null) { 
                        facesOnImage = new Vector<FaceDefinition>(10); 
                        hashtable.put(filename, facesOnImage); 
                    } 
 
                    // update the vector 
                    facesOnImage.add(face); 
 
                } else { 
                    System.err.println("Wrong number of tokens on line: " + line) ; 
                } 
 
            } 
            in.close(); 
        } 
        catch (IOException e) { 
            System.out.println(e); 
            return null; 
        } 
 
 
        return hashtable; 
 
    } 
 
    private static int doubleToString(String s) throws IOException { 
 
        try { 
            return (int) Double.parseDouble(s); 
        } catch (NumberFormatException e) { 
            throw new IOException("'" + s + "' is not a number"); 
        } 
 
    } 
 
}