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