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