Home | History | Annotate | Download | only in params
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 package android.hardware.camera2.params;
     19 
     20 import android.graphics.Point;
     21 import android.graphics.Rect;
     22 import android.hardware.camera2.CameraCharacteristics;
     23 import android.hardware.camera2.CameraMetadata;
     24 import android.hardware.camera2.CaptureResult;
     25 
     26 /**
     27  * Describes a face detected in an image.
     28  */
     29 public final class Face {
     30 
     31     /**
     32      * The ID is {@code -1} when the optional set of fields is unsupported.
     33      *
     34      * @see Face#Face(Rect, int)
     35      * @see #getId()
     36      */
     37     public static final int ID_UNSUPPORTED = -1;
     38 
     39     /**
     40      * The minimum possible value for the confidence level.
     41      *
     42      * @see #getScore()
     43      */
     44     public static final int SCORE_MIN = 1;
     45 
     46     /**
     47      * The maximum possible value for the confidence level.
     48      *
     49      * @see #getScore()
     50      */
     51     public static final int SCORE_MAX = 100;
     52 
     53     private final Rect mBounds;
     54     private final int mScore;
     55     private final int mId;
     56     private final Point mLeftEye;
     57     private final Point mRightEye;
     58     private final Point mMouth;
     59 
     60     /**
     61      * Create a new face with all fields set.
     62      *
     63      * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
     64      * They are only required when the {@link CaptureResult} reports that the value of key
     65      * {@link CaptureResult#STATISTICS_FACE_DETECT_MODE} is
     66      * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_FULL}.
     67      * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
     68      * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
     69      * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
     70      *
     71      * @param bounds Bounds of the face.
     72      * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
     73      * @param id A unique ID per face visible to the tracker.
     74      * @param leftEyePosition The position of the left eye.
     75      * @param rightEyePosition The position of the right eye.
     76      * @param mouthPosition The position of the mouth.
     77      *
     78      * @throws IllegalArgumentException
     79      *             if bounds is {@code null},
     80      *             or if the confidence is not in the range of
     81      *             {@value #SCORE_MIN}-{@value #SCORE_MAX},
     82      *             or if id is {@value #ID_UNSUPPORTED} and
     83      *               leftEyePosition/rightEyePosition/mouthPosition aren't all null,
     84      *             or else if id is negative.
     85      *
     86      * @hide
     87      */
     88     public Face(Rect bounds, int score, int id,
     89             Point leftEyePosition, Point rightEyePosition, Point mouthPosition) {
     90         checkNotNull("bounds", bounds);
     91         if (score < SCORE_MIN || score > SCORE_MAX) {
     92             throw new IllegalArgumentException("Confidence out of range");
     93         } else if (id < 0 && id != ID_UNSUPPORTED) {
     94             throw new IllegalArgumentException("Id out of range");
     95         }
     96         if (id == ID_UNSUPPORTED) {
     97             checkNull("leftEyePosition", leftEyePosition);
     98             checkNull("rightEyePosition", rightEyePosition);
     99             checkNull("mouthPosition", mouthPosition);
    100         }
    101 
    102         mBounds = bounds;
    103         mScore = score;
    104         mId = id;
    105         mLeftEye = leftEyePosition;
    106         mRightEye = rightEyePosition;
    107         mMouth = mouthPosition;
    108     }
    109 
    110     /**
    111      * Create a new face without the optional fields.
    112      *
    113      * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
    114      * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
    115      * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
    116      * rightEyePosition, and mouthPosition may be independently null or not-null. When devices
    117      * report the value of key {@link CaptureResult#STATISTICS_FACE_DETECT_MODE} as
    118      * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_SIMPLE} in {@link CaptureResult},
    119      * the face id of each face is expected to be {@value #ID_UNSUPPORTED}, the leftEyePosition,
    120      * rightEyePosition, and mouthPositions are expected to be {@code null} for each face.</p>
    121      *
    122      * @param bounds Bounds of the face.
    123      * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
    124      *
    125      * @throws IllegalArgumentException
    126      *             if bounds is {@code null},
    127      *             or if the confidence is not in the range of
    128      *             {@value #SCORE_MIN}-{@value #SCORE_MAX}.
    129      *
    130      * @hide
    131      */
    132     public Face(Rect bounds, int score) {
    133         this(bounds, score, ID_UNSUPPORTED,
    134                 /*leftEyePosition*/null, /*rightEyePosition*/null, /*mouthPosition*/null);
    135     }
    136 
    137     /**
    138      * Bounds of the face.
    139      *
    140      * <p>A rectangle relative to the sensor's
    141      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
    142      * representing the top-left corner of the active array rectangle.</p>
    143      *
    144      * <p>There is no constraints on the the Rectangle value other than it
    145      * is not-{@code null}.</p>
    146      */
    147     public Rect getBounds() {
    148         return mBounds;
    149     }
    150 
    151     /**
    152      * The confidence level for the detection of the face.
    153      *
    154      * <p>The range is {@value #SCORE_MIN} to {@value #SCORE_MAX}.
    155      * {@value #SCORE_MAX} is the highest confidence.</p>
    156      *
    157      * <p>Depending on the device, even very low-confidence faces may be
    158      * listed, so applications should filter out faces with low confidence,
    159      * depending on the use case. For a typical point-and-shoot camera
    160      * application that wishes to display rectangles around detected faces,
    161      * filtering out faces with confidence less than half of {@value #SCORE_MAX}
    162      * is recommended.</p>
    163      *
    164      * @see #SCORE_MAX
    165      * @see #SCORE_MIN
    166      */
    167     public int getScore() {
    168         return mScore;
    169     }
    170 
    171     /**
    172      * An unique id per face while the face is visible to the tracker.
    173      *
    174      * <p>
    175      * If the face leaves the field-of-view and comes back, it will get a new
    176      * id.</p>
    177      *
    178      * <p>This is an optional field, may not be supported on all devices.
    179      * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
    180      * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
    181      * rightEyePosition, and mouthPosition may be independently null or not-null. When devices
    182      * report the value of key {@link CaptureResult#STATISTICS_FACE_DETECT_MODE} as
    183      * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_SIMPLE} in {@link CaptureResult},
    184      * the face id of each face is expected to be {@value #ID_UNSUPPORTED}.</p>
    185      *
    186      * <p>This value will either be {@value #ID_UNSUPPORTED} or
    187      * otherwise greater than {@code 0}.</p>
    188      *
    189      * @see #ID_UNSUPPORTED
    190      */
    191     public int getId() {
    192         return mId;
    193     }
    194 
    195     /**
    196      * The coordinates of the center of the left eye.
    197      *
    198      * <p>The coordinates are in
    199      * the same space as the ones for {@link #getBounds}. This is an
    200      * optional field, may not be supported on all devices. If not
    201      * supported, the value will always be set to null.
    202      * This value will  always be null only if {@link #getId()} returns
    203      * {@value #ID_UNSUPPORTED}.</p>
    204      *
    205      * @return The left eye position, or {@code null} if unknown.
    206      */
    207     public Point getLeftEyePosition() {
    208         return mLeftEye;
    209     }
    210 
    211     /**
    212      * The coordinates of the center of the right eye.
    213      *
    214      * <p>The coordinates are
    215      * in the same space as the ones for {@link #getBounds}.This is an
    216      * optional field, may not be supported on all devices. If not
    217      * supported, the value will always be set to null.
    218      * This value will  always be null only if {@link #getId()} returns
    219      * {@value #ID_UNSUPPORTED}.</p>
    220      *
    221      * @return The right eye position, or {@code null} if unknown.
    222      */
    223     public Point getRightEyePosition() {
    224         return mRightEye;
    225     }
    226 
    227     /**
    228      * The coordinates of the center of the mouth.
    229      *
    230      * <p>The coordinates are in
    231      * the same space as the ones for {@link #getBounds}. This is an optional
    232      * field, may not be supported on all devices. If not
    233      * supported, the value will always be set to null.
    234      * This value will  always be null only if {@link #getId()} returns
    235      * {@value #ID_UNSUPPORTED}.</p>
    236      * </p>
    237      *
    238      * @return The mouth position, or {@code null} if unknown.
    239      */
    240     public Point getMouthPosition() {
    241         return mMouth;
    242     }
    243 
    244     /**
    245      * Represent the Face as a string for debugging purposes.
    246      */
    247     @Override
    248     public String toString() {
    249         return String.format("{ bounds: %s, score: %s, id: %d, " +
    250                 "leftEyePosition: %s, rightEyePosition: %s, mouthPosition: %s }",
    251                 mBounds, mScore, mId, mLeftEye, mRightEye, mMouth);
    252     }
    253 
    254     private static void checkNotNull(String name, Object obj) {
    255         if (obj == null) {
    256             throw new IllegalArgumentException(name + " was required, but it was null");
    257         }
    258     }
    259 
    260     private static void checkNull(String name, Object obj) {
    261         if (obj != null) {
    262             throw new IllegalArgumentException(name + " was required to be null, but it wasn't");
    263         }
    264     }
    265 }
    266