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; 031 032import java.io.DataInput; 033import java.io.DataOutput; 034import java.io.IOException; 035 036import org.openimaj.image.FImage; 037import org.openimaj.image.ImageUtilities; 038import org.openimaj.io.ReadWriteableBinary; 039import org.openimaj.math.geometry.shape.Rectangle; 040import org.openimaj.math.geometry.shape.Shape; 041 042/** 043 * A DetectedFace models a face detected by a face detector, together with the 044 * locations of certain facial features localised on the face. 045 * 046 * @author Jonathon Hare 047 * 048 */ 049public class DetectedFace implements ReadWriteableBinary { 050 /** 051 * The upright bounds of the face in the image in which it was detected 052 */ 053 protected Rectangle bounds; 054 055 /** 056 * The extracted sub-image representing the face. This is normally extracted 057 * directly from the bounds rectangle in the original image, but in some 058 * cases might be extracted from a sub-region of the bounds rectangle. 059 */ 060 protected FImage facePatch; 061 062 /** 063 * The confidence of the detection; higher numbers mean higher confidence. 064 */ 065 protected float confidence = 1; 066 067 /** 068 * Default constructor with an empty rectangle as bounds 069 */ 070 public DetectedFace() { 071 this.bounds = new Rectangle(); 072 } 073 074 /** 075 * Construct with a bounds rectangle (the bounding box of the face in the 076 * detection image) and an image patch that describes the contents of the 077 * bounds rectangle from the original image. 078 * 079 * @param bounds 080 * The bounding box of the face in the detection image. 081 * @param patch 082 * The subimage describing the contents of the bounding box. 083 * @param confidence 084 * The confidence of the detection. 085 */ 086 public DetectedFace(final Rectangle bounds, final FImage patch, final float confidence) { 087 this.bounds = bounds; 088 this.facePatch = patch; 089 this.confidence = confidence; 090 } 091 092 /** 093 * Returns the sub-image representing the face. 094 * @return Get the sub-image representing the detected face 095 */ 096 public FImage getFacePatch() { 097 return this.facePatch; 098 } 099 100 /** 101 * Reset the face patch image 102 * @param img The image 103 */ 104 public void setFacePatch( final FImage img ) 105 { 106 this.facePatch = img; 107 } 108 109 /** 110 * Get the bounding box of the face in the detection image. This might be 111 * the same as the shape returned by {@link #getShape()}, or it might 112 * encompass that shape. 113 * 114 * @return The bounding box of the face in the detection image 115 */ 116 public Rectangle getBounds() { 117 return this.bounds; 118 } 119 120 /** 121 * Set the bounds of this face. This is so that detected face objects 122 * can be updated if the bounds were inaccurate, or tracking is taking 123 * place on the object. 124 * @param rect The new bounds 125 */ 126 public void setBounds( final Rectangle rect ) 127 { 128 this.bounds = rect; 129 } 130 131 @Override 132 public void writeBinary(final DataOutput out) throws IOException { 133 this.bounds.writeBinary(out); 134 ImageUtilities.write(this.facePatch, "png", out); 135 } 136 137 @Override 138 public byte[] binaryHeader() { 139 return "DF".getBytes(); 140 } 141 142 @Override 143 public void readBinary(final DataInput in) throws IOException { 144 this.bounds.readBinary(in); 145 this.facePatch = ImageUtilities.readF(in); 146 } 147 148 /** 149 * Get the confidence of the detection. Higher numbers mean higher 150 * confidence. 151 * 152 * @return the confidence. 153 */ 154 public float getConfidence() { 155 return this.confidence; 156 } 157 158 /** 159 * Get the shape of the detection. In most cases, this will just return the 160 * bounds rectangle, however, subclasses can override to return a better 161 * geometric description of the detection area. 162 * 163 * @return the shape describing the detection in the original image. 164 */ 165 public Shape getShape() { 166 return this.bounds; 167 } 168 169 /** 170 * Set the confidence of the detection. Higher numbers mean higher 171 * confidence. 172 * 173 * @param confidence 174 * the confidence. 175 */ 176 public void setConfidence(final int confidence) { 177 this.confidence = confidence; 178 } 179}