1# Copyright 2018 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 os.path 16 17import its.caps 18import its.device 19import its.image 20import its.objects 21import its.target 22 23import numpy as np 24NAME = os.path.basename(__file__).split('.')[0] 25PATCH_SIZE = 0.0625 # 1/16 x 1/16 in center of image 26PATCH_LOC = (1-PATCH_SIZE)/2 27THRESH_DIFF = 0.06 28THRESH_GAIN = 0.1 29THRESH_EXP = 0.05 30 31 32def main(): 33 """Test both cameras give similar RBG values for gray patch.""" 34 35 yuv_sizes = {} 36 with its.device.ItsSession() as cam: 37 props = cam.get_camera_properties() 38 its.caps.skip_unless(its.caps.compute_target_exposure(props) and 39 its.caps.per_frame_control(props) and 40 its.caps.logical_multi_camera(props) and 41 its.caps.raw16(props) and 42 its.caps.manual_sensor(props)) 43 ids = its.caps.logical_multi_camera_physical_ids(props) 44 s, e, _, _, f = cam.do_3a(get_results=True) 45 req = its.objects.manual_capture_request(s, e, f) 46 max_raw_size = its.objects.get_available_output_sizes('raw', props)[0] 47 for i in ids: 48 physical_props = cam.get_camera_properties_by_id(i) 49 yuv_sizes[i] = its.objects.get_available_output_sizes( 50 'yuv', physical_props, match_ar_size=max_raw_size) 51 if i == ids[0]: 52 yuv_match_sizes = yuv_sizes[i] 53 else: 54 list(set(yuv_sizes[i]).intersection(yuv_match_sizes)) 55 yuv_match_sizes.sort() 56 w = yuv_match_sizes[-1][0] 57 h = yuv_match_sizes[-1][1] 58 print 'RAW size: (%d, %d)' % (max_raw_size[0], max_raw_size[1]) 59 print 'YUV size: (%d, %d)' % (w, h) 60 61 # capture YUVs 62 out_surfaces = [{'format': 'raw'}, 63 {'format': 'yuv', 'width': w, 'height': h, 64 'physicalCamera': ids[0]}, 65 {'format': 'yuv', 'width': w, 'height': h, 66 'physicalCamera': ids[1]}] 67 cap_raw, cap_yuv1, cap_yuv2 = cam.do_capture(req, out_surfaces) 68 69 img_raw = its.image.convert_capture_to_rgb_image(cap_raw, props=props) 70 its.image.write_image(img_raw, '%s_raw.jpg' % NAME) 71 rgb_means_raw = its.image.compute_image_means( 72 its.image.get_image_patch(img_raw, PATCH_LOC, PATCH_LOC, 73 PATCH_SIZE, PATCH_SIZE)) 74 75 img_yuv1 = its.image.convert_capture_to_rgb_image( 76 cap_yuv1, props=props) 77 its.image.write_image(img_yuv1, '%s_yuv1.jpg' % NAME) 78 y1, _, _ = its.image.convert_capture_to_planes( 79 cap_yuv1, props=props) 80 y1_mean = its.image.compute_image_means( 81 its.image.get_image_patch(y1, PATCH_LOC, PATCH_LOC, 82 PATCH_SIZE, PATCH_SIZE))[0] 83 84 img_yuv2 = its.image.convert_capture_to_rgb_image( 85 cap_yuv2, props=props) 86 its.image.write_image(img_yuv2, '%s_yuv2.jpg' % NAME) 87 y2, _, _ = its.image.convert_capture_to_planes( 88 cap_yuv2, props=props) 89 y2_mean = its.image.compute_image_means( 90 its.image.get_image_patch(y2, PATCH_LOC, PATCH_LOC, 91 PATCH_SIZE, PATCH_SIZE))[0] 92 print 'rgb_raw:', rgb_means_raw 93 print 'y1_mean:', y1_mean 94 print 'y2_mean:', y2_mean 95 96 # assert gain/exp values are near written values 97 s_yuv1 = cap_yuv1['metadata']['android.sensor.sensitivity'] 98 e_yuv1 = cap_yuv1['metadata']['android.sensor.exposureTime'] 99 msg = 'yuv_gain(write): %d, (read): %d' % (s, s_yuv1) 100 assert 0 <= s - s_yuv1 < s * THRESH_GAIN, msg 101 msg = 'yuv_exp(write): %.3fms, (read): %.3fms' % (e*1E6, e_yuv1*1E6) 102 assert 0 <= e - e_yuv1 < e * THRESH_EXP, msg 103 104 # compare YUVs 105 msg = 'y1: %.3f, y2: %.3f, TOL=%.5f' % (y1_mean, y2_mean, THRESH_DIFF) 106 assert np.isclose(y1_mean, y2_mean, rtol=THRESH_DIFF), msg 107 108 109if __name__ == '__main__': 110 main() 111