Home | History | Annotate | Download | only in tests
      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.device
     17 import its.objects
     18 import os
     19 import sys
     20 import numpy
     21 import Image
     22 import math
     23 import time
     24 import os.path
     25 
     26 def main():
     27     """Test that the android.tonemap.mode param is applied.
     28 
     29     Applies different tonemap curves to each R,G,B channel, and checks
     30     that the output images are modified as expected.
     31     """
     32     NAME = os.path.basename(__file__).split(".")[0]
     33 
     34     THRESHOLD_RATIO_MIN_DIFF = 0.1
     35     THRESHOLD_DIFF_MAX_DIFF = 0.05
     36 
     37     # TODO: Query the allowable tonemap curve sizes; here, it's hardcoded to
     38     # a length=64 list of tuples. The max allowed length should be inside the
     39     # camera properties object.
     40     L = 32
     41     LM1 = float(L-1)
     42 
     43     with its.device.ItsSession() as cam:
     44 
     45         # Test 1: that the tonemap curves have the expected effect. Take two
     46         # shots, with n in [0,1], where each has a linear tonemap, with the
     47         # n=1 shot having a steeper gradient. The gradient for each R,G,B
     48         # channel increases (i.e.) R[n=1] should be brighter than R[n=0],
     49         # and G[n=1] should be brighter than G[n=0] by a larger margin, etc.
     50         rgb_means = []
     51 
     52         for n in [0,1]:
     53             req = its.objects.manual_capture_request(100,50)
     54             req["android.tonemap.mode"] = 0
     55             req["android.tonemap.curveRed"] = (
     56                     sum([[i/LM1, (1+0.5*n)*i/LM1] for i in range(L)], []))
     57             req["android.tonemap.curveGreen"] = (
     58                     sum([[i/LM1, (1+1.0*n)*i/LM1] for i in range(L)], []))
     59             req["android.tonemap.curveBlue"] = (
     60                     sum([[i/LM1, (1+1.5*n)*i/LM1] for i in range(L)], []))
     61             fname, w, h, md = cam.do_capture(req)
     62             img = its.image.load_yuv420_to_rgb_image(fname, w, h)
     63             its.image.write_image(
     64                     img, "%s_n=%d.jpg" %(NAME, n))
     65             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
     66             rgb_means.append(its.image.compute_image_means(tile))
     67 
     68         rgb_ratios = [rgb_means[1][i] / rgb_means[0][i] for i in xrange(3)]
     69         print "Test 1: RGB ratios:", rgb_ratios
     70         assert(rgb_ratios[0] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[1])
     71         assert(rgb_ratios[1] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[2])
     72 
     73 
     74         # Test 2: that the length of the tonemap curve (i.e. number of control
     75         # points) doesn't affect the output.
     76         rgb_means = []
     77 
     78         for size in [32,64]:
     79             m = float(size-1)
     80             curve = sum([[i/m, i/m] for i in range(size)], [])
     81             req = its.objects.manual_capture_request(100,50)
     82             req["android.tonemap.mode"] = 0
     83             req["android.tonemap.curveRed"] = curve
     84             req["android.tonemap.curveGreen"] = curve
     85             req["android.tonemap.curveBlue"] = curve
     86             fname, w, h, md = cam.do_capture(req)
     87             img = its.image.load_yuv420_to_rgb_image(fname, w, h)
     88             its.image.write_image(
     89                     img, "%s_size=%02d.jpg" %(NAME, size))
     90             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
     91             rgb_means.append(its.image.compute_image_means(tile))
     92 
     93         rgb_diffs = [rgb_means[1][i] - rgb_means[0][i] for i in xrange(3)]
     94         print "Test 2: RGB diffs:", rgb_diffs
     95         assert(abs(rgb_diffs[0]) < THRESHOLD_DIFF_MAX_DIFF)
     96         assert(abs(rgb_diffs[1]) < THRESHOLD_DIFF_MAX_DIFF)
     97         assert(abs(rgb_diffs[2]) < THRESHOLD_DIFF_MAX_DIFF)
     98 
     99 if __name__ == '__main__':
    100     main()
    101 
    102