1# Copyright 2013 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"""Verifies settings latch on the correct frame.""" 15 16 17import logging 18import os.path 19import matplotlib 20from matplotlib import pylab 21from mobly import test_runner 22 23import its_base_test 24import camera_properties_utils 25import capture_request_utils 26import image_processing_utils 27import its_session_utils 28import target_exposure_utils 29 30EXP_GAIN_FACTOR = 2 31NAME = os.path.splitext(os.path.basename(__file__))[0] 32PATCH_H = 0.1 # center 10% 33PATCH_W = 0.1 34PATCH_X = 0.5 - PATCH_W/2 35PATCH_Y = 0.5 - PATCH_H/2 36REQ_PATTERN = ['base', 'base', 'iso', 'iso', 'base', 'base', 'exp', 37 'base', 'iso', 'base', 'exp', 'base', 'exp', 'exp'] 38PATTERN_CHECK = [False if r == 'base' else True for r in REQ_PATTERN] 39 40 41class LatchingTest(its_base_test.ItsBaseTest): 42 """Test that settings latch on the right frame. 43 44 Takes a sequence of 14 shots using back-to-back requests, varying the capture 45 request gain and exp parameters between shots. Check images that come back 46 have the properties. 47 48 Pattern is described in EXP_GAIN_HIGH_PATTERN where False is NOM, True is High 49 """ 50 51 def test_latching(self): 52 logging.debug('Starting %s', NAME) 53 with its_session_utils.ItsSession( 54 device_id=self.dut.serial, 55 camera_id=self.camera_id, 56 hidden_physical_id=self.hidden_physical_id) as cam: 57 props = cam.get_camera_properties() 58 props = cam.override_with_hidden_physical_camera_props(props) 59 log_path = self.log_path 60 61 # check SKIP conditions 62 camera_properties_utils.skip_unless( 63 camera_properties_utils.full_or_better(props)) 64 65 # Load chart for scene 66 its_session_utils.load_scene( 67 cam, props, self.scene, self.tablet, self.chart_distance) 68 69 # Create requests, do captures and extract means for each image 70 _, fmt = capture_request_utils.get_fastest_manual_capture_settings(props) 71 e, s = target_exposure_utils.get_target_exposure_combos( 72 log_path, cam)['midExposureTime'] 73 74 e /= EXP_GAIN_FACTOR 75 r_means = [] 76 g_means = [] 77 b_means = [] 78 reqs = [] 79 base_req = capture_request_utils.manual_capture_request( 80 s, e, 0.0, True, props) 81 iso_mult_req = capture_request_utils.manual_capture_request( 82 s * EXP_GAIN_FACTOR, e, 0.0, True, props) 83 exp_mult_req = capture_request_utils.manual_capture_request( 84 s, e * EXP_GAIN_FACTOR, 0.0, True, props) 85 for req_type in REQ_PATTERN: 86 if req_type == 'base': 87 reqs.append(base_req) 88 elif req_type == 'exp': 89 reqs.append(exp_mult_req) 90 elif req_type == 'iso': 91 reqs.append(iso_mult_req) 92 else: 93 assert 0, 'Incorrect capture request!' 94 95 caps = cam.do_capture(reqs, fmt) 96 for i, cap in enumerate(caps): 97 img = image_processing_utils.convert_capture_to_rgb_image(cap) 98 image_processing_utils.write_image(img, '%s_i=%02d.jpg' % ( 99 os.path.join(log_path, NAME), i)) 100 patch = image_processing_utils.get_image_patch( 101 img, PATCH_X, PATCH_Y, PATCH_W, PATCH_H) 102 rgb_means = image_processing_utils.compute_image_means(patch) 103 r_means.append(rgb_means[0]) 104 g_means.append(rgb_means[1]) 105 b_means.append(rgb_means[2]) 106 logging.debug('G means: %s', str(g_means)) 107 108 # Plot results 109 idxs = range(len(r_means)) 110 pylab.figure(NAME) 111 pylab.plot(idxs, r_means, '-ro') 112 pylab.plot(idxs, g_means, '-go') 113 pylab.plot(idxs, b_means, '-bo') 114 pylab.ylim([0, 1]) 115 pylab.title(NAME) 116 pylab.xlabel('capture') 117 pylab.ylabel('RGB means') 118 matplotlib.pyplot.savefig('%s_plot_means.png' % os.path.join( 119 log_path, NAME)) 120 121 # check G mean pattern for correctness 122 g_avg_for_caps = sum(g_means) / len(g_means) 123 g_high = [g / g_avg_for_caps > 1 for g in g_means] 124 assert g_high == PATTERN_CHECK, 'G means: %s, TEMPLATE: %s' % ( 125 str(g_means), str(REQ_PATTERN)) 126 127if __name__ == '__main__': 128 test_runner.main() 129 130