blob: 2acce85878cf6078fae9421b2f9b860812cc7e85 [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
Anders 4 Fridlundd62cb942016-12-09 14:15:57 +010016import its.caps
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070017import its.device
18import its.objects
19import os.path
20
21def main():
22 """Test face detection.
23 """
24 NAME = os.path.basename(__file__).split(".")[0]
25 NUM_TEST_FRAMES = 20
26 FD_MODE_OFF = 0
27 FD_MODE_SIMPLE = 1
28 FD_MODE_FULL = 2
Yin-Chia Yehd32a08d2016-10-05 17:06:55 -070029 W, H = 640, 480
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070030
31 with its.device.ItsSession() as cam:
32 props = cam.get_camera_properties()
33 fd_modes = props['android.statistics.info.availableFaceDetectModes']
34 a = props['android.sensor.info.activeArraySize']
35 aw, ah = a['right'] - a['left'], a['bottom'] - a['top']
Anders 4 Fridlundd62cb942016-12-09 14:15:57 +010036 if its.caps.read_3a(props):
37 gain, exp, _, _, focus = cam.do_3a(get_results=True)
38 print 'iso = %d' % gain
39 print 'exp = %.2fms' % (exp*1.0E-6)
40 if focus == 0.0:
41 print 'fd = infinity'
42 else:
43 print 'fd = %.2fcm' % (1.0E2/focus)
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070044 for fd_mode in fd_modes:
45 assert(FD_MODE_OFF <= fd_mode <= FD_MODE_FULL)
46 req = its.objects.auto_capture_request()
47 req['android.statistics.faceDetectMode'] = fd_mode
Yin-Chia Yehd32a08d2016-10-05 17:06:55 -070048 fmt = {"format":"yuv", "width":W, "height":H}
49 caps = cam.do_capture([req]*NUM_TEST_FRAMES, fmt)
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070050 for i,cap in enumerate(caps):
51 md = cap['metadata']
52 assert(md['android.statistics.faceDetectMode'] == fd_mode)
53 faces = md['android.statistics.faces']
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070054
55 # 0 faces should be returned for OFF mode
56 if fd_mode == FD_MODE_OFF:
57 assert(len(faces) == 0)
58 continue
59 # Face detection could take several frames to warm up,
60 # but it should detect at least one face in last frame
61 if i == NUM_TEST_FRAMES - 1:
Yin-Chia Yehd32a08d2016-10-05 17:06:55 -070062 img = its.image.convert_capture_to_rgb_image(cap, props=props)
Clemenz Portmannc47c8022017-04-04 09:10:30 -070063 img = its.image.rotate_img_per_argv(img)
Yin-Chia Yehd32a08d2016-10-05 17:06:55 -070064 img_name = "%s_fd_mode_%s.jpg" % (NAME, fd_mode)
65 its.image.write_image(img, img_name)
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070066 if len(faces) == 0:
67 print "Error: no face detected in mode", fd_mode
68 assert(0)
69 if len(faces) == 0:
70 continue
71
72 print "Frame %d face metadata:" % i
73 print " Faces:", faces
74 print ""
75
76 face_scores = [face['score'] for face in faces]
77 face_rectangles = [face['bounds'] for face in faces]
78 for score in face_scores:
79 assert(score >= 1 and score <= 100)
80 # Face bounds should be within active array
81 for rect in face_rectangles:
82 assert(rect['top'] < rect['bottom'])
83 assert(rect['left'] < rect['right'])
84 assert(0 <= rect['top'] <= ah)
85 assert(0 <= rect['bottom'] <= ah)
86 assert(0 <= rect['left'] <= aw)
87 assert(0 <= rect['right'] <= aw)
88
89 # Face landmarks are reported if and only if fd_mode is FULL
90 # Face ID should be -1 for SIMPLE and unique for FULL
91 if fd_mode == FD_MODE_SIMPLE:
92 for face in faces:
93 assert('leftEye' not in face)
94 assert('rightEye' not in face)
95 assert('mouth' not in face)
96 assert(face['id'] == -1)
97 elif fd_mode == FD_MODE_FULL:
98 face_ids = [face['id'] for face in faces]
99 assert(len(face_ids) == len(set(face_ids)))
100 # Face landmarks should be within face bounds
101 for face in faces:
102 left_eye = face['leftEye']
103 right_eye = face['rightEye']
104 mouth = face['mouth']
105 l, r = face['bounds']['left'], face['bounds']['right']
106 t, b = face['bounds']['top'], face['bounds']['bottom']
107 assert(l <= left_eye['x'] <= r)
108 assert(t <= left_eye['y'] <= b)
109 assert(l <= right_eye['x'] <= r)
110 assert(t <= right_eye['y'] <= b)
111 assert(l <= mouth['x'] <= r)
112 assert(t <= mouth['y'] <= b)
113
114if __name__ == '__main__':
115 main()
116