Home | History | Annotate | Download | only in scene3
      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 
     15 import os.path
     16 
     17 import its.caps
     18 import its.cv2image
     19 import its.device
     20 import its.image
     21 import its.objects
     22 import its.target
     23 
     24 import matplotlib
     25 from matplotlib import pylab
     26 import numpy
     27 
     28 NAME = os.path.basename(__file__).split(".")[0]
     29 NUM_SAMPLES = 4
     30 THRESH_REL_SHARPNESS_DIFF = 0.15
     31 
     32 
     33 def check_edge_modes(sharpness):
     34     """Check that the sharpness for the different edge modes is correct."""
     35     print " Verify HQ(2) is sharper than OFF(0)"
     36     assert sharpness[2] > sharpness[0]
     37 
     38     print " Verify ZSL(3) is similar to OFF(0)"
     39     e_msg = "ZSL: %.5f, OFF: %.5f, RTOL: %.2f" % (
     40             sharpness[3], sharpness[0], THRESH_REL_SHARPNESS_DIFF)
     41     assert numpy.isclose(sharpness[3], sharpness[0],
     42                          THRESH_REL_SHARPNESS_DIFF), e_msg
     43 
     44     print " Verify OFF(0) is not sharper than FAST(1)"
     45     assert sharpness[1] > sharpness[0] * (1.0 - THRESH_REL_SHARPNESS_DIFF)
     46 
     47     print " Verify FAST(1) is not sharper than HQ(2)"
     48     assert sharpness[2] > sharpness[1] * (1.0 - THRESH_REL_SHARPNESS_DIFF)
     49 
     50 
     51 def test_edge_mode(cam, edge_mode, sensitivity, exp, fd, out_surface, chart,
     52                    reprocess_format=None):
     53     """Return sharpness of the output images and the capture result metadata.
     54 
     55        Processes a capture request with a given edge mode, sensitivity, exposure
     56        time, focus distance, output surface parameter, and reprocess format
     57        (None for a regular request.)
     58 
     59     Args:
     60         cam: An open device session.
     61         edge_mode: Edge mode for the request as defined in android.edge.mode
     62         sensitivity: Sensitivity for the request as defined in
     63             android.sensor.sensitivity
     64         exp: Exposure time for the request as defined in
     65             android.sensor.exposureTime.
     66         fd: Focus distance for the request as defined in
     67             android.lens.focusDistance
     68         out_surface: Specifications of the output image format and size.
     69         chart: object containing chart information
     70         reprocess_format: (Optional) The reprocessing format. If not None,
     71                 reprocessing will be enabled.
     72 
     73     Returns:
     74         Object containing reported edge mode and the sharpness of the output
     75         image, keyed by the following strings:
     76             "edge_mode"
     77             "sharpness"
     78     """
     79 
     80     req = its.objects.manual_capture_request(sensitivity, exp)
     81     req["android.lens.focusDistance"] = fd
     82     req["android.edge.mode"] = edge_mode
     83     if reprocess_format:
     84         req["android.reprocess.effectiveExposureFactor"] = 1.0
     85 
     86     sharpness_list = []
     87     caps = cam.do_capture([req]*NUM_SAMPLES, [out_surface], reprocess_format)
     88     for n in range(NUM_SAMPLES):
     89         y, _, _ = its.image.convert_capture_to_planes(caps[n])
     90         chart.img = its.image.normalize_img(its.image.get_image_patch(
     91                 y, chart.xnorm, chart.ynorm, chart.wnorm, chart.hnorm))
     92         if n == 0:
     93             its.image.write_image(chart.img, "%s_reprocess_fmt_%s_edge=%d.jpg" %
     94                                   (NAME, reprocess_format, edge_mode))
     95             res_edge_mode = caps[n]["metadata"]["android.edge.mode"]
     96         sharpness_list.append(its.image.compute_image_sharpness(chart.img))
     97 
     98     ret = {}
     99     ret["edge_mode"] = res_edge_mode
    100     ret["sharpness"] = numpy.mean(sharpness_list)
    101 
    102     return ret
    103 
    104 
    105 def main():
    106     """Test android.edge.mode param applied when set for reprocessing requests.
    107 
    108     Capture non-reprocess images for each edge mode and calculate their
    109     sharpness as a baseline.
    110 
    111     Capture reprocessed images for each supported reprocess format and edge_mode
    112     mode. Calculate the sharpness of reprocessed images and compare them against
    113     the sharpess of non-reprocess images.
    114     """
    115 
    116     with its.device.ItsSession() as cam:
    117         props = cam.get_camera_properties()
    118 
    119         its.caps.skip_unless(its.caps.read_3a(props) and
    120                              its.caps.per_frame_control(props) and
    121                              its.caps.edge_mode(props, 0) and
    122                              (its.caps.yuv_reprocess(props) or
    123                               its.caps.private_reprocess(props)))
    124 
    125     # initialize chart class and locate chart in scene
    126     chart = its.cv2image.Chart()
    127 
    128     with its.device.ItsSession() as cam:
    129         mono_camera = its.caps.mono_camera(props)
    130         # If reprocessing is supported, ZSL EE mode must be avaiable.
    131         assert its.caps.edge_mode(props, 3), "EE mode not available!"
    132 
    133         reprocess_formats = []
    134         if its.caps.yuv_reprocess(props):
    135             reprocess_formats.append("yuv")
    136         if its.caps.private_reprocess(props):
    137             reprocess_formats.append("private")
    138 
    139         size = its.objects.get_available_output_sizes("jpg", props)[0]
    140         out_surface = {"width": size[0], "height": size[1], "format": "jpg"}
    141 
    142         # Get proper sensitivity, exposure time, and focus distance.
    143         s, e, _, _, fd = cam.do_3a(get_results=True, mono_camera=mono_camera)
    144 
    145         # Intialize plot
    146         pylab.figure("reprocess_result")
    147         gr_color = {"yuv": "r", "private": "g", "none": "b"}
    148 
    149         # Get the sharpness for each edge mode for regular requests
    150         sharpness_regular = []
    151         edge_mode_reported_regular = []
    152         for edge_mode in range(4):
    153             # Skip unavailable modes
    154             if not its.caps.edge_mode(props, edge_mode):
    155                 edge_mode_reported_regular.append(edge_mode)
    156                 sharpness_regular.append(0)
    157                 continue
    158             ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface, chart)
    159             edge_mode_reported_regular.append(ret["edge_mode"])
    160             sharpness_regular.append(ret["sharpness"])
    161 
    162         pylab.plot(range(4), sharpness_regular, "-"+gr_color["none"]+"o")
    163         print "Reported edge modes",
    164         print "regular requests:", edge_mode_reported_regular
    165         print "Sharpness with EE mode [0,1,2,3]:", sharpness_regular
    166         print ""
    167 
    168         # Get the sharpness for each reprocess format and edge mode for
    169         # reprocess requests.
    170         sharpnesses_reprocess = []
    171         edge_mode_reported_reprocess = []
    172 
    173         for reprocess_format in reprocess_formats:
    174             # List of sharpness
    175             sharpnesses = []
    176             edge_mode_reported = []
    177             for edge_mode in range(4):
    178                 # Skip unavailable modes
    179                 if not its.caps.edge_mode(props, edge_mode):
    180                     edge_mode_reported.append(edge_mode)
    181                     sharpnesses.append(0)
    182                     continue
    183 
    184                 ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface,
    185                                      chart, reprocess_format)
    186                 edge_mode_reported.append(ret["edge_mode"])
    187                 sharpnesses.append(ret["sharpness"])
    188 
    189             sharpnesses_reprocess.append(sharpnesses)
    190             edge_mode_reported_reprocess.append(edge_mode_reported)
    191 
    192             pylab.plot(range(4), sharpnesses,
    193                        "-"+gr_color[reprocess_format]+"o")
    194             print "Reported edge modes w/ request fmt %s:" % reprocess_format
    195             print "Sharpness with EE mode [0,1,2,3] for %s reprocess:" % (
    196                     reprocess_format), sharpnesses
    197             print ""
    198 
    199         # Finalize plot
    200         pylab.title("Red-YUV Reprocess  Green-Private Reprocess  Blue-None")
    201         pylab.xlabel("Edge Enhance Mode")
    202         pylab.ylabel("Sharpness")
    203         pylab.xticks(range(4))
    204         matplotlib.pyplot.savefig("%s_plot_EE.png" %
    205                                   ("test_reprocess_edge_enhancement"))
    206         print "regular requests:"
    207         check_edge_modes(sharpness_regular)
    208 
    209         for reprocess_format in range(len(reprocess_formats)):
    210             print "\nreprocess format:", reprocess_format
    211             check_edge_modes(sharpnesses_reprocess[reprocess_format])
    212 
    213             hq_div_off_reprocess = (sharpnesses_reprocess[reprocess_format][2] /
    214                                     sharpnesses_reprocess[reprocess_format][0])
    215             hq_div_off_regular = sharpness_regular[2] / sharpness_regular[0]
    216             e_msg = "HQ/OFF_reprocess: %.4f, HQ/OFF_reg: %.4f, RTOL: %.2f" % (
    217                     hq_div_off_reprocess, hq_div_off_regular,
    218                     THRESH_REL_SHARPNESS_DIFF)
    219             print " Verify reprocess HQ(2) ~= reg HQ(2) relative to OFF(0)"
    220             assert numpy.isclose(hq_div_off_reprocess, hq_div_off_regular,
    221                                  THRESH_REL_SHARPNESS_DIFF), e_msg
    222 
    223 if __name__ == "__main__":
    224     main()
    225 
    226