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.image.processing.face.detection.benchmarking; 031 032import java.io.BufferedReader; 033import java.io.File; 034import java.io.FileReader; 035import java.io.IOException; 036import java.util.ArrayList; 037import java.util.List; 038 039import org.openimaj.data.dataset.ListBackedDataset; 040import org.openimaj.image.FImage; 041import org.openimaj.image.ImageUtilities; 042import org.openimaj.image.MBFImage; 043import org.openimaj.image.processing.face.detection.DetectedFace; 044import org.openimaj.image.processing.face.detection.EllipticalDetectedFace; 045import org.openimaj.math.geometry.shape.Ellipse; 046import org.openimaj.math.geometry.shape.EllipseUtilities; 047 048public class FDDBDataset extends ListBackedDataset<FDDBRecord> { 049 class Record implements FDDBRecord { 050 String imageName; 051 private List<DetectedFace> groundTruth; 052 053 @Override 054 public String getImageName() { 055 return imageName; 056 } 057 058 @Override 059 public FImage getFImage() { 060 try { 061 return ImageUtilities.readF(new File(imageBase, imageName + imageExtension)); 062 } catch (final IOException e) { 063 throw new RuntimeException(e); 064 } 065 } 066 067 @Override 068 public MBFImage getMBFImage() { 069 try { 070 return ImageUtilities.readMBF(new File(imageBase, imageName + imageExtension)); 071 } catch (final IOException e) { 072 throw new RuntimeException(e); 073 } 074 } 075 076 @Override 077 public List<? extends DetectedFace> getGroundTruth() { 078 return groundTruth; 079 } 080 } 081 082 File imageBase; 083 final String imageExtension = ".jpg"; 084 085 public FDDBDataset(File fddbGroundTruth, File imageBase, boolean loadImages) throws IOException { 086 this.data = new ArrayList<FDDBRecord>(); 087 this.imageBase = imageBase; 088 089 read(fddbGroundTruth, loadImages); 090 } 091 092 private void read(File fddbGroundTruth, boolean loadImages) throws IOException { 093 BufferedReader br = null; 094 try { 095 br = new BufferedReader(new FileReader(fddbGroundTruth)); 096 097 String imageName; 098 while ((imageName = br.readLine()) != null) { 099 final Record r = new Record(); 100 r.imageName = imageName; 101 r.groundTruth = new ArrayList<DetectedFace>(); 102 103 final int nDet = Integer.parseInt(br.readLine()); 104 for (int i = 0; i < nDet; i++) { 105 final String[] parts = br.readLine().split("\\s+"); 106 107 if (parts.length != 6) 108 throw new IOException("bad format"); 109 110 final double major = Double.parseDouble(parts[0]); 111 final double minor = Double.parseDouble(parts[1]); 112 final double theta = Double.parseDouble(parts[2]); 113 final double x = Double.parseDouble(parts[3]); 114 final double y = Double.parseDouble(parts[4]); 115 final float confidence = Float.parseFloat(parts[5]); 116 117 final Ellipse ellipse = EllipseUtilities.ellipseFromEquation(x, y, major, minor, theta); 118 119 EllipticalDetectedFace detection; 120 if (!loadImages) { 121 detection = new EllipticalDetectedFace(ellipse, null, confidence); 122 } else { 123 detection = new EllipticalDetectedFace(ellipse, r.getFImage(), confidence); 124 } 125 126 r.groundTruth.add(detection); 127 } 128 129 this.data.add(r); 130 } 131 132 } finally { 133 if (br != null) 134 try { 135 br.close(); 136 } catch (final IOException e) { 137 } 138 } 139 } 140}