ITS: add checks for android.control.availableEffects
bug: 117979055
bug: 112369094
Change-Id: I150b419dfe61ba39a55eee1240dcb1c7c5be13c1
diff --git a/apps/CameraITS/tests/scene2/test_effects.py b/apps/CameraITS/tests/scene2/test_effects.py
new file mode 100644
index 0000000..7d034f2
--- /dev/null
+++ b/apps/CameraITS/tests/scene2/test_effects.py
@@ -0,0 +1,104 @@
+# 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 = 40 # min spread for U & V channels [0:255] for color image
+YUV_Y_SPREAD_MIN = 100 # 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)
+ 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()