Home | History | Annotate | Download | only in scene3
      1 # Copyright 2016 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 import cv2
     17 
     18 import its.caps
     19 import its.cv2image
     20 import its.device
     21 import its.image
     22 import its.objects
     23 import numpy as np
     24 
     25 NAME = os.path.basename(__file__).split('.')[0]
     26 CHART_FILE = os.path.join(os.environ['CAMERA_ITS_TOP'], 'pymodules', 'its',
     27                           'test_images', 'ISO12233.png')
     28 CHART_ORIENTATIONS = ['nominal', 'flip', 'mirror', 'rotate']
     29 VGA_WIDTH = 640
     30 VGA_HEIGHT = 480
     31 (X_CROP, Y_CROP) = (0.5, 0.5)  # crop center area of ISO12233 chart
     32 
     33 
     34 def test_flip_mirror(cam, props, fmt, chart):
     35     """Return if image is flipped or mirrored.
     36 
     37     Args:
     38         cam (class): An open device session
     39         props (class): Properties of cam
     40         fmt (dict): Capture format
     41         chart (class): Object with chart properties
     42 
     43     Returns:
     44         boolean: True if flipped, False if not
     45     """
     46 
     47     # determine if monochrome camera
     48     mono_camera = its.caps.mono_camera(props)
     49 
     50     # determine if in debug mode
     51     debug = its.caps.debug_mode()
     52 
     53     # get a local copy of the chart template
     54     template = cv2.imread(CHART_FILE, cv2.IMREAD_ANYDEPTH)
     55 
     56     # take img, crop chart, scale and prep for cv2 template match
     57     s, e, _, _, fd = cam.do_3a(get_results=True, mono_camera=mono_camera)
     58     req = its.objects.manual_capture_request(s, e, fd)
     59     cap = cam.do_capture(req, fmt)
     60     y, _, _ = its.image.convert_capture_to_planes(cap, props)
     61     y = its.image.rotate_img_per_argv(y)
     62     patch = its.image.get_image_patch(y, chart.xnorm, chart.ynorm,
     63                                       chart.wnorm, chart.hnorm)
     64     patch = 255 * its.cv2image.gray_scale_img(patch)
     65     patch = its.cv2image.scale_img(patch.astype(np.uint8), chart.scale)
     66 
     67     # sanity check on image
     68     assert np.max(patch)-np.min(patch) > 255/8
     69 
     70     # save full images if in debug
     71     if debug:
     72         its.image.write_image(template[:, :, np.newaxis]/255.0,
     73                               '%s_template.jpg' % NAME)
     74 
     75     # save patch
     76     its.image.write_image(patch[:, :, np.newaxis]/255.0,
     77                           '%s_scene_patch.jpg' % NAME)
     78 
     79     # crop center areas and strip off any extra rows/columns
     80     template = its.image.get_image_patch(template, (1-X_CROP)/2, (1-Y_CROP)/2,
     81                                          X_CROP, Y_CROP)
     82     patch = its.image.get_image_patch(patch, (1-X_CROP)/2,
     83                                       (1-Y_CROP)/2, X_CROP, Y_CROP)
     84     patch = patch[0:min(patch.shape[0], template.shape[0]),
     85                   0:min(patch.shape[1], template.shape[1])]
     86     comp_chart = patch
     87 
     88     # determine optimum orientation
     89     opts = []
     90     for orientation in CHART_ORIENTATIONS:
     91         if orientation == 'flip':
     92             comp_chart = np.flipud(patch)
     93         elif orientation == 'mirror':
     94             comp_chart = np.fliplr(patch)
     95         elif orientation == 'rotate':
     96             comp_chart = np.flipud(np.fliplr(patch))
     97         correlation = cv2.matchTemplate(comp_chart, template, cv2.TM_CCOEFF)
     98         _, opt_val, _, _ = cv2.minMaxLoc(correlation)
     99         if debug:
    100             cv2.imwrite('%s_%s.jpg' % (NAME, orientation), comp_chart)
    101         print ' %s correlation value: %d' % (orientation, opt_val)
    102         opts.append(opt_val)
    103 
    104     # determine if 'nominal' or 'rotated' is best orientation
    105     assert_flag = (opts[0] == max(opts) or opts[3] == max(opts))
    106     assert assert_flag, ('Optimum orientation is %s' %
    107                          CHART_ORIENTATIONS[np.argmax(opts)])
    108     # print warning if rotated
    109     if opts[3] == max(opts):
    110         print 'Image is rotated 180 degrees. Try "rotate" flag.'
    111 
    112 
    113 def main():
    114     """Test if image is properly oriented."""
    115 
    116     print '\nStarting test_flip_mirror.py'
    117 
    118     # check skip conditions
    119     with its.device.ItsSession() as cam:
    120         props = cam.get_camera_properties()
    121         its.caps.skip_unless(its.caps.read_3a(props))
    122     # initialize chart class and locate chart in scene
    123     chart = its.cv2image.Chart()
    124 
    125     with its.device.ItsSession() as cam:
    126         fmt = {'format': 'yuv', 'width': VGA_WIDTH, 'height': VGA_HEIGHT}
    127 
    128         # test that image is not flipped, mirrored, or rotated
    129         test_flip_mirror(cam, props, fmt, chart)
    130 
    131 
    132 if __name__ == '__main__':
    133     main()
    134