Home | History | Annotate | Download | only in scene0
      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 os
     16 
     17 import its.caps
     18 import its.device
     19 import its.image
     20 import its.objects
     21 import numpy as np
     22 
     23 NAME = os.path.basename(__file__).split('.')[0]
     24 PATTERNS = [1, 2]
     25 COLOR_BAR_ORDER = ['WHITE', 'YELLOW', 'CYAN', 'GREEN', 'MAGENTA', 'RED',
     26                    'BLUE', 'BLACK']
     27 COLOR_CHECKER = {'BLACK': [0, 0, 0], 'RED': [1, 0, 0], 'GREEN': [0, 1, 0],
     28                  'BLUE': [0, 0, 1], 'MAGENTA': [1, 0, 1], 'CYAN': [0, 1, 1],
     29                  'YELLOW': [1, 1, 0], 'WHITE': [1, 1, 1]}
     30 CH_TOL = 2E-3  # 1/2 DN in [0:1]
     31 LSFR_COEFFS = 0b100010000  # PN9
     32 
     33 
     34 def check_solid_color(cap, props):
     35     """Simple test for solid color.
     36 
     37     Args:
     38         cap: capture element
     39         props: capture properties
     40     Returns:
     41         True/False
     42     """
     43     print 'Checking solid TestPattern...'
     44     r, gr, gb, b = its.image.convert_capture_to_planes(cap, props)
     45     r_tile = its.image.get_image_patch(r, 0.0, 0.0, 1.0, 1.0)
     46     gr_tile = its.image.get_image_patch(gr, 0.0, 0.0, 1.0, 1.0)
     47     gb_tile = its.image.get_image_patch(gb, 0.0, 0.0, 1.0, 1.0)
     48     b_tile = its.image.get_image_patch(b, 0.0, 0.0, 1.0, 1.0)
     49     var_max = max(np.amax(r_tile), np.amax(gr_tile), np.amax(gb_tile),
     50                   np.amax(b_tile))
     51     var_min = min(np.amin(r_tile), np.amin(gr_tile), np.amin(gb_tile),
     52                   np.amin(b_tile))
     53     white_level = int(props['android.sensor.info.whiteLevel'])
     54     print ' pixel min: %.f, pixel max: %.f' % (white_level*var_min,
     55                                                white_level*var_max)
     56     return np.isclose(var_max, var_min, atol=CH_TOL)
     57 
     58 
     59 def check_color_bars(cap, props, mirror=False):
     60     """Test image for color bars.
     61 
     62     Compute avg of bars and compare to ideal
     63 
     64     Args:
     65         cap:            capture element
     66         props:          capture properties
     67         mirror (bool):  whether to mirror image or not
     68     Returns:
     69         True/False
     70     """
     71     print 'Checking color bar TestPattern...'
     72     delta = 0.0005
     73     num_bars = len(COLOR_BAR_ORDER)
     74     color_match = []
     75     img = its.image.convert_capture_to_rgb_image(cap, props=props)
     76     if mirror:
     77         print ' Image mirrored'
     78         img = np.fliplr(img)
     79     for i, color in enumerate(COLOR_BAR_ORDER):
     80         tile = its.image.get_image_patch(img, float(i)/num_bars+delta,
     81                                          0.0, 1.0/num_bars-2*delta, 1.0)
     82         color_match.append(np.allclose(its.image.compute_image_means(tile),
     83                                        COLOR_CHECKER[color], atol=CH_TOL))
     84     print COLOR_BAR_ORDER
     85     print color_match
     86     return all(color_match)
     87 
     88 
     89 def check_pattern(cap, props, pattern):
     90     """Simple tests for pattern correctness.
     91 
     92     Args:
     93         cap: capture element
     94         props: capture properties
     95         pattern (int): valid number for pattern
     96     Returns:
     97         boolean
     98     """
     99 
    100     # white_level = int(props['android.sensor.info.whiteLevel'])
    101     if pattern == 1:  # solid color
    102         return check_solid_color(cap, props)
    103 
    104     elif pattern == 2:  # color bars
    105         striped = check_color_bars(cap, props, mirror=False)
    106         # check mirrored version in case image rotated from sensor orientation
    107         if not striped:
    108             striped = check_color_bars(cap, props, mirror=True)
    109         return striped
    110 
    111     else:
    112         print 'No specific test for TestPattern %d' % pattern
    113         return True
    114 
    115 
    116 def test_test_patterns(cam, props, af_fd):
    117     """test image sensor test patterns.
    118 
    119     Args:
    120         cam: An open device session.
    121         props: Properties of cam
    122         af_fd: Focus distance
    123     """
    124 
    125     avail_patterns = props['android.sensor.availableTestPatternModes']
    126     print 'avail_patterns: ', avail_patterns
    127     sens_min, _ = props['android.sensor.info.sensitivityRange']
    128     exposure = min(props['android.sensor.info.exposureTimeRange'])
    129 
    130     for pattern in PATTERNS:
    131         if pattern in avail_patterns:
    132             req = its.objects.manual_capture_request(int(sens_min),
    133                                                      exposure)
    134             req['android.lens.focusDistance'] = af_fd
    135             req['android.sensor.testPatternMode'] = pattern
    136             fmt = {'format': 'raw'}
    137             cap = cam.do_capture(req, fmt)
    138             img = its.image.convert_capture_to_rgb_image(cap, props=props)
    139 
    140             # Save pattern
    141             its.image.write_image(img, '%s_%d.jpg' % (NAME, pattern), True)
    142 
    143             # Check pattern for correctness
    144             assert check_pattern(cap, props, pattern)
    145         else:
    146             print 'Pattern not in android.sensor.availableTestPatternModes.'
    147 
    148 
    149 def main():
    150     """Test pattern generation test.
    151 
    152     Test: capture frames for each valid test pattern and check if
    153     generated correctly.
    154     android.sensor.testPatternMode
    155     0: OFF
    156     1: SOLID_COLOR
    157     2: COLOR_BARS
    158     3: COLOR_BARS_FADE_TO_GREY
    159     4: PN9
    160     """
    161 
    162     print '\nStarting %s' % NAME
    163     with its.device.ItsSession() as cam:
    164         props = cam.get_camera_properties()
    165         its.caps.skip_unless(its.caps.raw16(props) and
    166                              its.caps.manual_sensor(props) and
    167                              its.caps.per_frame_control(props))
    168 
    169         # For test pattern, use min_fd
    170         fd = props['android.lens.info.minimumFocusDistance']
    171         test_test_patterns(cam, props, fd)
    172 
    173 if __name__ == '__main__':
    174     main()
    175