| # Copyright 2015 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import os |
| |
| import its.caps |
| import its.device |
| import its.image |
| import its.objects |
| |
| import matplotlib |
| from matplotlib import pylab |
| import numpy |
| |
| NAME = os.path.basename(__file__).split('.')[0] |
| NUM_SHADING_MODE_SWITCH_LOOPS = 3 |
| THRESHOLD_DIFF_RATIO = 0.15 |
| |
| |
| def main(): |
| """Test that the android.shading.mode param is applied. |
| |
| Switching shading modes and checks that the lens shading maps are |
| modified as expected. |
| """ |
| |
| with its.device.ItsSession() as cam: |
| props = cam.get_camera_properties() |
| |
| its.caps.skip_unless(its.caps.per_frame_control(props) and |
| its.caps.lsc_map(props) and |
| its.caps.lsc_off(props)) |
| |
| mono_camera = its.caps.mono_camera(props) |
| |
| # lsc_off devices should always support OFF(0), FAST(1), and HQ(2) |
| assert(props.has_key('android.shading.availableModes') and |
| set(props['android.shading.availableModes']) == set([0, 1, 2])) |
| |
| # Test 1: Switching shading modes several times and verify: |
| # 1. Lens shading maps with mode OFF are all 1.0 |
| # 2. Lens shading maps with mode FAST are similar after switching |
| # shading modes. |
| # 3. Lens shading maps with mode HIGH_QUALITY are similar after |
| # switching shading modes. |
| cam.do_3a(mono_camera=mono_camera) |
| |
| # Get the reference lens shading maps for OFF, FAST, and HIGH_QUALITY |
| # in different sessions. |
| # reference_maps[mode] |
| reference_maps = [[] for mode in range(3)] |
| num_map_gains = 0 |
| for mode in range(1, 3): |
| req = its.objects.auto_capture_request() |
| req['android.statistics.lensShadingMapMode'] = 1 |
| req['android.shading.mode'] = mode |
| cap_res = cam.do_capture(req)['metadata'] |
| lsc_map = cap_res['android.statistics.lensShadingCorrectionMap'] |
| assert(lsc_map.has_key('width') and |
| lsc_map.has_key('height') and |
| lsc_map['width'] is not None and |
| lsc_map['height'] is not None) |
| if mode == 1: |
| num_map_gains = lsc_map['width'] * lsc_map['height'] * 4 |
| reference_maps[0] = [1.0] * num_map_gains |
| reference_maps[mode] = lsc_map['map'] |
| |
| # Get the lens shading maps while switching modes in one session. |
| reqs = [] |
| for i in range(NUM_SHADING_MODE_SWITCH_LOOPS): |
| for mode in range(3): |
| req = its.objects.auto_capture_request() |
| req['android.statistics.lensShadingMapMode'] = 1 |
| req['android.shading.mode'] = mode |
| reqs.append(req) |
| |
| caps = cam.do_capture(reqs) |
| |
| # shading_maps[mode][loop] |
| shading_maps = [[[] for loop in range(NUM_SHADING_MODE_SWITCH_LOOPS)] |
| for mode in range(3)] |
| |
| # Get the shading maps out of capture results |
| for i in range(len(caps)): |
| shading_maps[i % 3][i / 3] = \ |
| caps[i]['metadata']['android.statistics.lensShadingCorrectionMap']['map'] |
| |
| # Draw the maps |
| for mode in range(3): |
| for i in range(NUM_SHADING_MODE_SWITCH_LOOPS): |
| pylab.clf() |
| pylab.plot(range(num_map_gains), shading_maps[mode][i], '-ro') |
| pylab.plot(range(num_map_gains), reference_maps[mode], '-go') |
| pylab.xlim([0, num_map_gains]) |
| pylab.ylim([0.9, 4.0]) |
| name = '%s_ls_maps_mode_%d_loop_%d' % (NAME, mode, i) |
| pylab.title(name) |
| pylab.xlabel('Map gains') |
| pylab.ylabel('Lens shading maps') |
| matplotlib.pyplot.savefig('%s.png' % name) |
| |
| print 'Verifying lens shading maps with mode OFF are all 1.0' |
| for i in range(NUM_SHADING_MODE_SWITCH_LOOPS): |
| assert numpy.allclose(shading_maps[0][i], reference_maps[0]) |
| |
| for mode in range(1, 3): |
| print 'Verifying lens shading maps with mode', mode, 'are similar' |
| for i in range(NUM_SHADING_MODE_SWITCH_LOOPS): |
| assert(numpy.allclose(shading_maps[mode][i], |
| reference_maps[mode], |
| THRESHOLD_DIFF_RATIO)) |
| |
| if __name__ == '__main__': |
| main() |