Home | History | Annotate | Download | only in scene1
      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 
     15 import its.image
     16 import its.caps
     17 import its.device
     18 import its.objects
     19 import its.target
     20 import numpy
     21 import math
     22 import pylab
     23 import os.path
     24 import matplotlib
     25 import matplotlib.pyplot
     26 
     27 def main():
     28     """Test that device processing can be inverted to linear pixels.
     29 
     30     Captures a sequence of shots with the device pointed at a uniform
     31     target. Attempts to invert all the ISP processing to get back to
     32     linear R,G,B pixel data.
     33     """
     34     NAME = os.path.basename(__file__).split(".")[0]
     35 
     36     RESIDUAL_THRESHOLD = 0.0003 # approximately each sample is off by 2/255
     37 
     38     # The HAL3.2 spec requires that curves up to 64 control points in length
     39     # must be supported.
     40     L = 64
     41     LM1 = float(L-1)
     42 
     43     gamma_lut = numpy.array(
     44             sum([[i/LM1, math.pow(i/LM1, 1/2.2)] for i in xrange(L)], []))
     45     inv_gamma_lut = numpy.array(
     46             sum([[i/LM1, math.pow(i/LM1, 2.2)] for i in xrange(L)], []))
     47 
     48     with its.device.ItsSession() as cam:
     49         props = cam.get_camera_properties()
     50         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
     51                              its.caps.per_frame_control(props))
     52 
     53         e,s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
     54         s /= 2
     55         sens_range = props['android.sensor.info.sensitivityRange']
     56         sensitivities = [s*1.0/3.0, s*2.0/3.0, s, s*4.0/3.0, s*5.0/3.0]
     57         sensitivities = [s for s in sensitivities
     58                 if s > sens_range[0] and s < sens_range[1]]
     59 
     60         req = its.objects.manual_capture_request(0, e)
     61         req["android.blackLevel.lock"] = True
     62         req["android.tonemap.mode"] = 0
     63         req["android.tonemap.curveRed"] = gamma_lut.tolist()
     64         req["android.tonemap.curveGreen"] = gamma_lut.tolist()
     65         req["android.tonemap.curveBlue"] = gamma_lut.tolist()
     66 
     67         r_means = []
     68         g_means = []
     69         b_means = []
     70 
     71         for sens in sensitivities:
     72             req["android.sensor.sensitivity"] = sens
     73             cap = cam.do_capture(req)
     74             img = its.image.convert_capture_to_rgb_image(cap)
     75             its.image.write_image(
     76                     img, "%s_sens=%04d.jpg" % (NAME, sens))
     77             img = its.image.apply_lut_to_image(img, inv_gamma_lut[1::2] * LM1)
     78             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
     79             rgb_means = its.image.compute_image_means(tile)
     80             r_means.append(rgb_means[0])
     81             g_means.append(rgb_means[1])
     82             b_means.append(rgb_means[2])
     83 
     84         pylab.plot(sensitivities, r_means, 'r')
     85         pylab.plot(sensitivities, g_means, 'g')
     86         pylab.plot(sensitivities, b_means, 'b')
     87         pylab.ylim([0,1])
     88         matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
     89 
     90         # Check that each plot is actually linear.
     91         for means in [r_means, g_means, b_means]:
     92             line,residuals,_,_,_  = numpy.polyfit(range(5),means,1,full=True)
     93             print "Line: m=%f, b=%f, resid=%f"%(line[0], line[1], residuals[0])
     94             assert(residuals[0] < RESIDUAL_THRESHOLD)
     95 
     96 if __name__ == '__main__':
     97     main()
     98 
     99