1# Copyright 2015 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.caps
16import its.device
17import its.image
18import its.objects
19import matplotlib
20import numpy
21import os
22import os.path
23from matplotlib import pylab
24
25def main():
26    """Test that the android.shading.mode param is applied.
27
28    Switching shading modes and checks that the lens shading maps are
29    modified as expected.
30    """
31    NAME = os.path.basename(__file__).split(".")[0]
32
33    NUM_SHADING_MODE_SWITCH_LOOPS = 3
34    THRESHOLD_DIFF_RATIO = 0.15
35
36    with its.device.ItsSession() as cam:
37        props = cam.get_camera_properties()
38
39        its.caps.skip_unless(its.caps.per_frame_control(props) and
40                             its.caps.lsc_map(props) and
41                             its.caps.lsc_off(props))
42
43        mono_camera = its.caps.mono_camera(props)
44
45        # lsc_off devices should always support OFF(0), FAST(1), and HQ(2)
46        assert(props.has_key("android.shading.availableModes") and
47               set(props["android.shading.availableModes"]) == set([0, 1, 2]))
48
49        # Test 1: Switching shading modes several times and verify:
50        #   1. Lens shading maps with mode OFF are all 1.0
51        #   2. Lens shading maps with mode FAST are similar after switching
52        #      shading modes.
53        #   3. Lens shading maps with mode HIGH_QUALITY are similar after
54        #      switching shading modes.
55        cam.do_3a(mono_camera=mono_camera);
56
57        # Get the reference lens shading maps for OFF, FAST, and HIGH_QUALITY
58        # in different sessions.
59        # reference_maps[mode]
60        reference_maps = [[] for mode in range(3)]
61        num_map_gains = 0
62        for mode in range(1, 3):
63            req = its.objects.auto_capture_request();
64            req["android.statistics.lensShadingMapMode"] = 1
65            req["android.shading.mode"] = mode
66            cap_res = cam.do_capture(req)["metadata"]
67            lsc_map = cap_res["android.statistics.lensShadingCorrectionMap"]
68            assert(lsc_map.has_key("width") and
69                   lsc_map.has_key("height") and
70                   lsc_map["width"] != None and lsc_map["height"] != None)
71            if mode == 1:
72                num_map_gains = lsc_map["width"] * lsc_map["height"] * 4
73                reference_maps[0] = [1.0] * num_map_gains
74            reference_maps[mode] = lsc_map["map"]
75
76        # Get the lens shading maps while switching modes in one session.
77        reqs = []
78        for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
79            for mode in range(3):
80                req = its.objects.auto_capture_request();
81                req["android.statistics.lensShadingMapMode"] = 1
82                req["android.shading.mode"] = mode
83                reqs.append(req);
84
85        caps = cam.do_capture(reqs)
86
87        # shading_maps[mode][loop]
88        shading_maps = [[[] for loop in range(NUM_SHADING_MODE_SWITCH_LOOPS)]
89                for mode in range(3)]
90
91        # Get the shading maps out of capture results
92        for i in range(len(caps)):
93            shading_maps[i % 3][i / 3] = \
94                    caps[i]["metadata"] \
95                    ["android.statistics.lensShadingCorrectionMap"]["map"]
96
97        # Draw the maps
98        for mode in range(3):
99            for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
100                pylab.clf()
101                pylab.plot(range(num_map_gains), shading_maps[mode][i], 'r')
102                pylab.plot(range(num_map_gains), reference_maps[mode], 'g')
103                pylab.xlim([0, num_map_gains])
104                pylab.ylim([0.9, 4.0])
105                matplotlib.pyplot.savefig("%s_ls_maps_mode_%d_loop_%d.png" %
106                                          (NAME, mode, i))
107
108        print "Verifying lens shading maps with mode OFF are all 1.0"
109        for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
110            assert(numpy.allclose(shading_maps[0][i], reference_maps[0]))
111
112        for mode in range(1, 3):
113            print "Verifying lens shading maps with mode", mode, "are similar"
114            for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
115                assert(numpy.allclose(shading_maps[mode][i],
116                                      reference_maps[mode],
117                                      THRESHOLD_DIFF_RATIO))
118
119if __name__ == '__main__':
120    main()
121