1# Copyright 2018 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 15import os.path 16import its.caps 17import its.device 18import its.image 19import its.objects 20import numpy as np 21 22# android.control.availableEffects 23EFFECTS = {0: 'OFF', 24 1: 'MONO', 25 2: 'NEGATIVE', 26 3: 'SOLARIZE', 27 4: 'SEPIA', 28 5: 'POSTERIZE', 29 6: 'WHITEBOARD', 30 7: 'BLACKBOARD', 31 8: 'AQUA'} 32MONO_UV_SPREAD_MAX = 2 # max spread for U & V channels [0:255] for mono image 33NAME = os.path.basename(__file__).split('.')[0] 34W, H = 640, 480 35YUV_MAX = 255.0 # normalization number for YUV images [0:1] --> [0:255] 36YUV_UV_SPREAD_MIN = 10 # min spread for U & V channels [0:255] for color image 37YUV_Y_SPREAD_MIN = 50 # min spread for Y channel [0:255] for color image 38 39 40def main(): 41 """Test effects. 42 43 Test: capture frame for supported camera effects and check if generated 44 correctly. Note we only check effects OFF and MONO currently, but save 45 images for all supported effects. 46 """ 47 48 print '\nStarting %s' % NAME 49 with its.device.ItsSession() as cam: 50 props = cam.get_camera_properties() 51 mono_camera = its.caps.mono_camera(props) 52 effects = props['android.control.availableEffects'] 53 its.caps.skip_unless(effects != [0]) 54 cam.do_3a(mono_camera=mono_camera) 55 print 'Supported effects:', effects 56 failed = [] 57 for effect in effects: 58 req = its.objects.auto_capture_request() 59 req['android.control.effectMode'] = effect 60 fmt = {'format': 'yuv', 'width': W, 'height': H} 61 cap = cam.do_capture(req, fmt) 62 63 # Save image 64 img = its.image.convert_capture_to_rgb_image(cap, props=props) 65 its.image.write_image(img, '%s_%s.jpg' % (NAME, EFFECTS[effect])) 66 67 # Simple checks 68 if effect is 0: 69 print 'Checking effects OFF...' 70 y, u, v = its.image.convert_capture_to_planes(cap, props) 71 y_min, y_max = np.amin(y)*YUV_MAX, np.amax(y)*YUV_MAX 72 msg = 'Y_range:%.f,%.f THRESH:%d, ' % ( 73 y_min, y_max, YUV_Y_SPREAD_MIN) 74 if (y_max-y_min) < YUV_Y_SPREAD_MIN: 75 failed.append({'effect': EFFECTS[effect], 'error': msg}) 76 if not mono_camera: 77 u_min, u_max = np.amin(u)*YUV_MAX, np.amax(u)*YUV_MAX 78 v_min, v_max = np.amin(v)*YUV_MAX, np.amax(v)*YUV_MAX 79 msg += 'U_range:%.f,%.f THRESH:%d, ' % ( 80 u_min, u_max, YUV_UV_SPREAD_MIN) 81 msg += 'V_range:%.f,%.f THRESH:%d' % ( 82 v_min, v_max, YUV_UV_SPREAD_MIN) 83 if ((u_max-u_min) < YUV_UV_SPREAD_MIN or 84 (v_max-v_min) < YUV_UV_SPREAD_MIN): 85 failed.append({'effect': EFFECTS[effect], 'error': msg}) 86 if effect is 1: 87 print 'Checking MONO effect...' 88 _, u, v = its.image.convert_capture_to_planes(cap, props) 89 u_min, u_max = np.amin(u)*YUV_MAX, np.amax(u)*YUV_MAX 90 v_min, v_max = np.amin(v)*YUV_MAX, np.amax(v)*YUV_MAX 91 msg = 'U_range:%.f,%.f, ' % (u_min, u_max) 92 msg += 'V_range:%.f,%.f, TOL:%d' % ( 93 v_min, v_max, MONO_UV_SPREAD_MAX) 94 if ((u_max-u_min) > MONO_UV_SPREAD_MAX or 95 (v_max-v_min) > MONO_UV_SPREAD_MAX): 96 failed.append({'effect': EFFECTS[effect], 'error': msg}) 97 if failed: 98 print 'Failed effects:' 99 for fail in failed: 100 print ' %s: %s' % (fail['effect'], fail['error']) 101 assert not failed 102 103 104if __name__ == '__main__': 105 main() 106