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.image
16import its.caps
17import its.device
18import its.objects
19import its.target
20import math
21import matplotlib
22import matplotlib.pyplot
23import numpy
24import os.path
25from matplotlib import pylab
26
27
28def test_edge_mode(cam, edge_mode, sensitivity, exp, fd, out_surface):
29    """Return sharpness of the output image and the capture result metadata
30       for a capture request with the given edge mode, sensitivity, exposure
31       time, focus distance, output surface parameter.
32
33    Args:
34        cam: An open device session.
35        edge_mode: Edge mode for the request as defined in android.edge.mode
36        sensitivity: Sensitivity for the request as defined in
37            android.sensor.sensitivity
38        exp: Exposure time for the request as defined in
39            android.sensor.exposureTime.
40        fd: Focus distance for the request as defined in
41            android.lens.focusDistance
42        output_surface: Specifications of the output image format and size.
43
44    Returns:
45        Object containing reported edge mode and the sharpness of the output
46        image, keyed by the following strings:
47            "edge_mode"
48            "sharpness"
49    """
50
51    NAME = os.path.basename(__file__).split(".")[0]
52    NUM_SAMPLES = 4
53
54    req = its.objects.manual_capture_request(sensitivity, exp)
55    req["android.lens.focusDistance"] = fd
56    req["android.edge.mode"] = edge_mode
57
58    sharpness_list = []
59    test_fmt = out_surface["format"]
60    for n in range(NUM_SAMPLES):
61        cap = cam.do_capture(req, out_surface, repeat_request=req)
62        img = its.image.convert_capture_to_rgb_image(cap)
63        if n == 0:
64            its.image.write_image(img, "%s_edge=%d.jpg" % (NAME, edge_mode))
65            res_edge_mode = cap["metadata"]["android.edge.mode"]
66        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
67        sharpness_list.append(its.image.compute_image_sharpness(tile))
68
69    ret = {}
70    ret["edge_mode"] = res_edge_mode
71    ret["sharpness"] = numpy.mean(sharpness_list)
72
73    return ret
74
75def main():
76    """Test that the android.edge.mode param is applied correctly.
77
78    Capture non-reprocess images for each edge mode and calculate their
79    sharpness as a baseline.
80    """
81
82    THRESHOLD_RELATIVE_SHARPNESS_DIFF = 0.1
83
84    with its.device.ItsSession() as cam:
85        props = cam.get_camera_properties()
86
87        its.caps.skip_unless(its.caps.read_3a(props) and
88                             its.caps.per_frame_control(props) and
89                             its.caps.edge_mode(props, 0))
90
91        test_fmt = "yuv"
92        size = its.objects.get_available_output_sizes(test_fmt, props)[0]
93        out_surface = {"width":size[0], "height":size[1], "format":test_fmt}
94
95        # Get proper sensitivity, exposure time, and focus distance.
96        s,e,_,_,fd = cam.do_3a(get_results=True)
97
98        # Get the sharpness for each edge mode for regular requests
99        sharpness_regular = []
100        edge_mode_reported_regular = []
101        for edge_mode in range(4):
102            # Skip unavailable modes
103            if not its.caps.edge_mode(props, edge_mode):
104                edge_mode_reported_regular.append(edge_mode)
105                sharpness_regular.append(0)
106                continue
107            ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface)
108            edge_mode_reported_regular.append(ret["edge_mode"])
109            sharpness_regular.append(ret["sharpness"])
110
111        print "Reported edge modes:", edge_mode_reported_regular
112        print "Sharpness with EE mode [0,1,2,3]:", sharpness_regular
113
114        # Verify HQ(2) is sharper than OFF(0)
115        assert(sharpness_regular[2] > sharpness_regular[0])
116
117        # Verify OFF(0) is not sharper than FAST(1)
118        assert(sharpness_regular[1] >
119               sharpness_regular[0] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
120
121        # Verify FAST(1) is not sharper than HQ(2)
122        assert(sharpness_regular[2] >
123               sharpness_regular[1] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
124
125if __name__ == '__main__':
126    main()
127
128