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.tools.faces;
031
032import org.openimaj.feature.FloatFV;
033import org.openimaj.feature.FloatFVComparison;
034import org.openimaj.image.FImage;
035import org.openimaj.image.processing.face.alignment.AffineAligner;
036import org.openimaj.image.processing.face.detection.DetectedFace;
037import org.openimaj.image.processing.face.detection.FaceDetector;
038import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
039import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
040import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
041import org.openimaj.image.processing.face.feature.DoGSIFTFeature;
042import org.openimaj.image.processing.face.feature.FacePatchFeature;
043import org.openimaj.image.processing.face.feature.FacialFeatureExtractor;
044import org.openimaj.image.processing.face.feature.LocalLBPHistogram;
045import org.openimaj.image.processing.face.feature.comparison.DoGSIFTFeatureComparator;
046import org.openimaj.image.processing.face.feature.comparison.FaceFVComparator;
047import org.openimaj.image.processing.face.feature.comparison.FacialFeatureComparator;
048import org.openimaj.image.processing.face.feature.comparison.ReversedLtpDtFeatureComparator;
049import org.openimaj.image.processing.face.feature.ltp.LtpDtFeature;
050import org.openimaj.image.processing.face.feature.ltp.TruncatedWeighting;
051import org.openimaj.image.processing.face.similarity.FaceSimilarityEngine;
052
053public enum PredefinedStrategy {
054        SIFT {
055                @Override
056                public FaceSimilarityEngine<?, ?, FImage> strategy() {
057                        final FacialFeatureComparator<DoGSIFTFeature> comparator = new DoGSIFTFeatureComparator();
058                        final FaceDetector<DetectedFace, FImage> detector = new HaarCascadeDetector(80);
059                        final FacialFeatureExtractor<DoGSIFTFeature, DetectedFace> factory = new DoGSIFTFeature.Extractor();
060
061                        return FaceSimilarityEngine.create(detector, factory, comparator);
062                }
063
064                @Override
065                public String description() {
066                        return "SIFT features using a TransformedOneToOnePointModel for feature matching and the SIFT vector for comparison.";
067                }
068        },
069        LOCAL_TRINARY_PATTERN {
070                @Override
071                public FaceSimilarityEngine<?, ?, FImage> strategy() {
072                        final FacialFeatureComparator<LtpDtFeature> comparator = new ReversedLtpDtFeatureComparator();
073                        final FKEFaceDetector detector = new FKEFaceDetector();
074                        final FacialFeatureExtractor<LtpDtFeature, KEDetectedFace> factory =
075                                        new LtpDtFeature.Extractor<KEDetectedFace>(
076                                                        new AffineAligner(),
077                                                        new TruncatedWeighting()
078                                        );
079
080                        return FaceSimilarityEngine.create(detector, factory, comparator);
081                }
082
083                @Override
084                public String description() {
085                        return "Local Ternary Pattern feature using truncated distance-maps for comparison. Faces aligned using affine transform.";
086                }
087        },
088        FACEPATCH_EUCLIDEAN {
089                @Override
090                public FaceSimilarityEngine<?, ?, FImage> strategy() {
091                        final FacialFeatureExtractor<FacePatchFeature, KEDetectedFace> factory = new FacePatchFeature.Extractor();
092                        final FacialFeatureComparator<FacePatchFeature> comparator = new FaceFVComparator<FacePatchFeature, FloatFV>(
093                                        FloatFVComparison.EUCLIDEAN);
094                        final FKEFaceDetector detector = new FKEFaceDetector();
095
096                        return FaceSimilarityEngine.create(detector, factory, comparator);
097                }
098
099                @Override
100                public String description() {
101                        return "Patched facial features, compared as a big vector using Euclidean distance.";
102                }
103        },
104        LOCAL_BINARY_PATTERN {
105                @Override
106                public FaceSimilarityEngine<?, ?, FImage> strategy() {
107                        // FacialFeatureFactory<LocalLBPHistogram, KEDetectedFace> factory =
108                        // new LocalLBPHistogram.Factory<KEDetectedFace>(new
109                        // AffineAligner(), 20, 20, 8, 1);
110                        // FacialFeatureFactory<LocalLBPHistogram, KEDetectedFace> factory =
111                        // new LocalLBPHistogram.Factory<KEDetectedFace>(new
112                        // AffineAligner(), 7, 7, 16, 4);
113                        final FacialFeatureExtractor<LocalLBPHistogram, KEDetectedFace> factory = new LocalLBPHistogram.Extractor<KEDetectedFace>(
114                                        new AffineAligner(), 7, 7, 8, 2);
115                        final FacialFeatureComparator<LocalLBPHistogram> comparator = new FaceFVComparator<LocalLBPHistogram, FloatFV>(
116                                        FloatFVComparison.CHI_SQUARE);
117                        final FKEFaceDetector detector = new FKEFaceDetector();
118
119                        return FaceSimilarityEngine.create(detector, factory, comparator);
120                }
121
122                @Override
123                public String description() {
124                        return "Local LBP histograms compared using Chi squared distance. Faces aligned using affine transform.";
125                }
126
127        },
128        ;
129
130        public abstract FaceSimilarityEngine<?, ?, FImage> strategy();
131
132        public abstract String description();
133}