blob: ba4f31795a490122092dab92bc4e4072db497c46 [file] [log] [blame]
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -07001# Copyright 2014 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import its.image
16import its.device
17import its.objects
18import os.path
19
20def main():
21 """Test face detection.
22 """
23 NAME = os.path.basename(__file__).split(".")[0]
24 NUM_TEST_FRAMES = 20
25 FD_MODE_OFF = 0
26 FD_MODE_SIMPLE = 1
27 FD_MODE_FULL = 2
28
29 with its.device.ItsSession() as cam:
30 props = cam.get_camera_properties()
31 fd_modes = props['android.statistics.info.availableFaceDetectModes']
32 a = props['android.sensor.info.activeArraySize']
33 aw, ah = a['right'] - a['left'], a['bottom'] - a['top']
Clemenz Portmannf7f23ee2016-08-18 13:00:59 -070034 gain, exp, _, _, focus = cam.do_3a(get_results=True)
35 print 'iso = %d' % gain
36 print 'exp = %.2fms' % (exp*1.0E-6)
Yin-Chia Yeh04a63332016-09-12 14:52:47 -070037 if focus == 0.0:
38 print 'fd = infinity'
39 else:
40 print 'fd = %.2fcm' % (1.0E2/focus)
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070041 for fd_mode in fd_modes:
42 assert(FD_MODE_OFF <= fd_mode <= FD_MODE_FULL)
43 req = its.objects.auto_capture_request()
44 req['android.statistics.faceDetectMode'] = fd_mode
45 caps = cam.do_capture([req]*NUM_TEST_FRAMES)
46 for i,cap in enumerate(caps):
47 md = cap['metadata']
48 assert(md['android.statistics.faceDetectMode'] == fd_mode)
49 faces = md['android.statistics.faces']
Clemenz Portmannf7f23ee2016-08-18 13:00:59 -070050 img = its.image.convert_capture_to_rgb_image(cap, props=props)
51 img_name = "%s_fd_mode_%s.jpg" % (NAME, fd_mode)
52 its.image.write_image(img, img_name)
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070053
54 # 0 faces should be returned for OFF mode
55 if fd_mode == FD_MODE_OFF:
56 assert(len(faces) == 0)
57 continue
58 # Face detection could take several frames to warm up,
59 # but it should detect at least one face in last frame
60 if i == NUM_TEST_FRAMES - 1:
61 if len(faces) == 0:
62 print "Error: no face detected in mode", fd_mode
63 assert(0)
64 if len(faces) == 0:
65 continue
66
67 print "Frame %d face metadata:" % i
68 print " Faces:", faces
69 print ""
70
71 face_scores = [face['score'] for face in faces]
72 face_rectangles = [face['bounds'] for face in faces]
73 for score in face_scores:
74 assert(score >= 1 and score <= 100)
75 # Face bounds should be within active array
76 for rect in face_rectangles:
77 assert(rect['top'] < rect['bottom'])
78 assert(rect['left'] < rect['right'])
79 assert(0 <= rect['top'] <= ah)
80 assert(0 <= rect['bottom'] <= ah)
81 assert(0 <= rect['left'] <= aw)
82 assert(0 <= rect['right'] <= aw)
83
84 # Face landmarks are reported if and only if fd_mode is FULL
85 # Face ID should be -1 for SIMPLE and unique for FULL
86 if fd_mode == FD_MODE_SIMPLE:
87 for face in faces:
88 assert('leftEye' not in face)
89 assert('rightEye' not in face)
90 assert('mouth' not in face)
91 assert(face['id'] == -1)
92 elif fd_mode == FD_MODE_FULL:
93 face_ids = [face['id'] for face in faces]
94 assert(len(face_ids) == len(set(face_ids)))
95 # Face landmarks should be within face bounds
96 for face in faces:
97 left_eye = face['leftEye']
98 right_eye = face['rightEye']
99 mouth = face['mouth']
100 l, r = face['bounds']['left'], face['bounds']['right']
101 t, b = face['bounds']['top'], face['bounds']['bottom']
102 assert(l <= left_eye['x'] <= r)
103 assert(t <= left_eye['y'] <= b)
104 assert(l <= right_eye['x'] <= r)
105 assert(t <= right_eye['y'] <= b)
106 assert(l <= mouth['x'] <= r)
107 assert(t <= mouth['y'] <= b)
108
109if __name__ == '__main__':
110 main()
111