# Copyright 2018 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os.path import its.caps import its.device import its.image import its.objects import numpy as np # android.control.availableEffects EFFECTS = {0: 'OFF', 1: 'MONO', 2: 'NEGATIVE', 3: 'SOLARIZE', 4: 'SEPIA', 5: 'POSTERIZE', 6: 'WHITEBOARD', 7: 'BLACKBOARD', 8: 'AQUA'} MONO_UV_SPREAD_MAX = 2 # max spread for U & V channels [0:255] for mono image NAME = os.path.basename(__file__).split('.')[0] W, H = 640, 480 YUV_MAX = 255.0 # normalization number for YUV images [0:1] --> [0:255] YUV_UV_SPREAD_MIN = 10 # min spread for U & V channels [0:255] for color image YUV_Y_SPREAD_MIN = 50 # min spread for Y channel [0:255] for color image def main(): """Test effects. Test: capture frame for supported camera effects and check if generated correctly. Note we only check effects OFF and MONO currently, but save images for all supported effects. """ print '\nStarting %s' % NAME with its.device.ItsSession() as cam: props = cam.get_camera_properties() mono_camera = its.caps.mono_camera(props) effects = props['android.control.availableEffects'] its.caps.skip_unless(effects != [0]) cam.do_3a(mono_camera=mono_camera) print 'Supported effects:', effects failed = [] for effect in effects: req = its.objects.auto_capture_request() req['android.control.effectMode'] = effect fmt = {'format': 'yuv', 'width': W, 'height': H} cap = cam.do_capture(req, fmt) # Save image img = its.image.convert_capture_to_rgb_image(cap, props=props) its.image.write_image(img, '%s_%s.jpg' % (NAME, EFFECTS[effect])) # Simple checks if effect is 0: print 'Checking effects OFF...' y, u, v = its.image.convert_capture_to_planes(cap, props) y_min, y_max = np.amin(y)*YUV_MAX, np.amax(y)*YUV_MAX msg = 'Y_range:%.f,%.f THRESH:%d, ' % ( y_min, y_max, YUV_Y_SPREAD_MIN) if (y_max-y_min) < YUV_Y_SPREAD_MIN: failed.append({'effect': EFFECTS[effect], 'error': msg}) if not mono_camera: u_min, u_max = np.amin(u)*YUV_MAX, np.amax(u)*YUV_MAX v_min, v_max = np.amin(v)*YUV_MAX, np.amax(v)*YUV_MAX msg += 'U_range:%.f,%.f THRESH:%d, ' % ( u_min, u_max, YUV_UV_SPREAD_MIN) msg += 'V_range:%.f,%.f THRESH:%d' % ( v_min, v_max, YUV_UV_SPREAD_MIN) if ((u_max-u_min) < YUV_UV_SPREAD_MIN or (v_max-v_min) < YUV_UV_SPREAD_MIN): failed.append({'effect': EFFECTS[effect], 'error': msg}) if effect is 1: print 'Checking MONO effect...' _, u, v = its.image.convert_capture_to_planes(cap, props) u_min, u_max = np.amin(u)*YUV_MAX, np.amax(u)*YUV_MAX v_min, v_max = np.amin(v)*YUV_MAX, np.amax(v)*YUV_MAX msg = 'U_range:%.f,%.f, ' % (u_min, u_max) msg += 'V_range:%.f,%.f, TOL:%d' % ( v_min, v_max, MONO_UV_SPREAD_MAX) if ((u_max-u_min) > MONO_UV_SPREAD_MAX or (v_max-v_min) > MONO_UV_SPREAD_MAX): failed.append({'effect': EFFECTS[effect], 'error': msg}) if failed: print 'Failed effects:' for fail in failed: print ' %s: %s' % (fail['effect'], fail['error']) assert not failed if __name__ == '__main__': main()