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.feature.ltp; 031 032import java.io.DataInput; 033import java.io.DataOutput; 034import java.io.IOException; 035 036import org.openimaj.citation.annotation.Reference; 037import org.openimaj.citation.annotation.ReferenceType; 038import org.openimaj.image.FImage; 039import org.openimaj.image.processing.face.alignment.FaceAligner; 040import org.openimaj.image.processing.face.detection.DetectedFace; 041import org.openimaj.image.processing.face.feature.FacialFeatureExtractor; 042import org.openimaj.io.IOUtils; 043 044/** 045 * The LTP based feature using a truncated Euclidean distance transform 046 * to estimate the distances within each slice. 047 * 048 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 049 */ 050@Reference( 051 type = ReferenceType.Article, 052 author = { "Xiaoyang Tan", "Triggs, B." }, 053 title = "Enhanced Local Texture Feature Sets for Face Recognition Under Difficult Lighting Conditions", 054 year = "2010", 055 journal = "Image Processing, IEEE Transactions on", 056 pages = { "1635 ", "1650" }, 057 month = "june ", 058 number = "6", 059 volume = "19", 060 customData = { 061 "keywords", "CAS-PEAL-R1;Gabor wavelets;PCA;distance transform based matching;extended Yale-B;face recognition;kernel-based feature extraction;local binary patterns;local spatial histograms;local ternary patterns;local texture feature set enhancement;local texture-based face representations;multiple feature fusion;principal component analysis;robust illumination normalization;face recognition;feature extraction;image enhancement;image fusion;image representation;image texture;principal component analysis;wavelet transforms;Algorithms;Biometry;Face;Humans;Image Enhancement;Image Interpretation, Computer-Assisted;Imaging, Three-Dimensional;Lighting;Pattern Recognition, Automated;Reproducibility of Results;Sensitivity and Specificity;Subtraction Technique;", 062 "doi", "10.1109/TIP.2010.2042645", 063 "ISSN", "1057-7149" 064 } 065 ) 066public class LtpDtFeature extends AbstractLtpDtFeature { 067 /** 068 * A {@link FacialFeatureExtractor} for extracting {@link LtpDtFeature}s. 069 * 070 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 071 * 072 * @param <Q> Type of detected face 073 */ 074 public static class Extractor<Q extends DetectedFace> implements FacialFeatureExtractor<LtpDtFeature, Q> { 075 LTPWeighting weighting; 076 FaceAligner<Q> aligner; 077 078 protected Extractor() {} 079 080 /** 081 * Construct the extractor with the given face aligner and weighting scheme. 082 * @param aligner the aligner. 083 * @param weighting the weighting scheme. 084 */ 085 public Extractor(FaceAligner<Q> aligner, LTPWeighting weighting) { 086 this.aligner = aligner; 087 this.weighting = weighting; 088 } 089 090 @Override 091 public LtpDtFeature extractFeature(Q detectedFace) { 092 FImage face = aligner.align(detectedFace); 093 FImage mask = aligner.getMask(); 094 095 return new LtpDtFeature(face, mask, weighting); 096 } 097 098 @Override 099 public void readBinary(DataInput in) throws IOException { 100 String weightingClass = in.readUTF(); 101 weighting = IOUtils.newInstance(weightingClass); 102 weighting.readBinary(in); 103 104 String alignerClass = in.readUTF(); 105 aligner = IOUtils.newInstance(alignerClass); 106 aligner.readBinary(in); 107 } 108 109 @Override 110 public byte[] binaryHeader() { 111 return this.getClass().getName().getBytes(); 112 } 113 114 @Override 115 public void writeBinary(DataOutput out) throws IOException { 116 out.writeUTF(weighting.getClass().getName()); 117 weighting.writeBinary(out); 118 119 out.writeUTF(aligner.getClass().getName()); 120 aligner.writeBinary(out); 121 } 122 123 @Override 124 public String toString() { 125 return "LtpDtFeature.Factory[weighting="+weighting+"]"; 126 } 127 } 128 129 /** 130 * Construct a {@link LtpDtFeature} feature. 131 * 132 * @param face the aligned face image 133 * @param mask the mask 134 * @param weighting the weighting scheme 135 */ 136 public LtpDtFeature(FImage face, FImage mask, LTPWeighting weighting) { 137 super(face.width, face.height, weighting, extractLTPSlicePixels(normaliseImage(face, mask))); 138 } 139}