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}