diff options
Diffstat (limited to 'apps/CameraITS/tests/scene1')
29 files changed, 0 insertions, 2479 deletions
diff --git a/apps/CameraITS/tests/scene1/README b/apps/CameraITS/tests/scene1/README deleted file mode 100755 index 93543d9..0000000 --- a/apps/CameraITS/tests/scene1/README +++ /dev/null @@ -1,16 +0,0 @@ -Scene 1 description: -* Camera on tripod in portrait or landscape orientation -* Scene mostly filled by grey card, with white background behind grey card -* Illuminated by simple light source, for example a desk lamp -* Uniformity of lighting and target positioning need not be precise - -This is intended to be a very simple setup that can be recreated on an -engineer's desk without any large or expensive equipment. The tests for this -scene in general only look at a patch in the middle of the image (which is -assumed to be within the bounds of the grey card). - -Note that the scene should not be completely uniform; don't have the grey card -100% fill the field of view and use a high quality uniform light source, for -example, and don't use a diffuser on top of the camera to simulate a grey -scene. - diff --git a/apps/CameraITS/tests/scene1/test_3a.py b/apps/CameraITS/tests/scene1/test_3a.py deleted file mode 100644 index b53fc73..0000000 --- a/apps/CameraITS/tests/scene1/test_3a.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2013 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 its.device -import its.caps - -def main(): - """Basic test for bring-up of 3A. - - To pass, 3A must converge. Check that the returned 3A values are legal. - """ - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.read_3a(props): - print "Test skipped" - return - - sens, exp, gains, xform, focus = cam.do_3a(get_results=True) - print "AE: sensitivity %d, exposure %dms" % (sens, exp/1000000) - print "AWB: gains", gains, "transform", xform - print "AF: distance", focus - assert(sens > 0) - assert(exp > 0) - assert(len(gains) == 4) - assert(len(xform) == 9) - assert(focus >= 0) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py b/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py deleted file mode 100644 index 59b7db1..0000000 --- a/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2014 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 its.device -import its.caps -import its.objects -import its.target - -def main(): - """Test the AE state machine when using the precapture trigger. - """ - - INACTIVE = 0 - SEARCHING = 1 - CONVERGED = 2 - LOCKED = 3 - FLASHREQUIRED = 4 - PRECAPTURE = 5 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - _,fmt = its.objects.get_fastest_manual_capture_settings(props) - - # Capture 5 manual requests, with AE disabled, and the last request - # has an AE precapture trigger (which should be ignored since AE is - # disabled). - manual_reqs = [] - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - manual_req = its.objects.manual_capture_request(s,e) - manual_req['android.control.aeMode'] = 0 # Off - manual_reqs += [manual_req]*4 - precap_req = its.objects.manual_capture_request(s,e) - precap_req['android.control.aeMode'] = 0 # Off - precap_req['android.control.aePrecaptureTrigger'] = 1 # Start - manual_reqs.append(precap_req) - caps = cam.do_capture(manual_reqs, fmt) - for cap in caps: - assert(cap['metadata']['android.control.aeState'] == INACTIVE) - - # Capture an auto request and verify the AE state; no trigger. - auto_req = its.objects.auto_capture_request() - auto_req['android.control.aeMode'] = 1 # On - cap = cam.do_capture(auto_req, fmt) - state = cap['metadata']['android.control.aeState'] - print "AE state after auto request:", state - assert(state in [SEARCHING, CONVERGED]) - - # Capture with auto request with a precapture trigger. - auto_req['android.control.aePrecaptureTrigger'] = 1 # Start - cap = cam.do_capture(auto_req, fmt) - state = cap['metadata']['android.control.aeState'] - print "AE state after auto request with precapture trigger:", state - assert(state in [SEARCHING, CONVERGED, PRECAPTURE]) - - # Capture some more auto requests, and AE should converge. - auto_req['android.control.aePrecaptureTrigger'] = 0 - caps = cam.do_capture([auto_req]*5, fmt) - state = caps[-1]['metadata']['android.control.aeState'] - print "AE state after auto request:", state - assert(state == CONVERGED) - -if __name__ == '__main__': - main() diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py deleted file mode 100644 index a9d5ce4..0000000 --- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import os.path -import math - -def main(): - """Capture auto and manual shots that should look the same. - - Manual shots taken with just manual WB, and also with manual WB+tonemap. - - In all cases, the general color/look of the shots should be the same, - however there can be variations in brightness/contrast due to different - "auto" ISP blocks that may be disabled in the manual flows. - """ - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.manual_sensor(props) or - not its.caps.manual_post_proc(props)): - print "Test skipped" - return - - # Converge 3A and get the estimates. - sens, exp, gains, xform, focus = cam.do_3a(get_results=True) - xform_rat = its.objects.float_to_rational(xform) - print "AE sensitivity %d, exposure %dms" % (sens, exp/1000000.0) - print "AWB gains", gains - print "AWB transform", xform - print "AF distance", focus - - # Auto capture. - req = its.objects.auto_capture_request() - cap_auto = cam.do_capture(req) - img_auto = its.image.convert_capture_to_rgb_image(cap_auto) - its.image.write_image(img_auto, "%s_auto.jpg" % (NAME)) - xform_a = its.objects.rational_to_float( - cap_auto["metadata"]["android.colorCorrection.transform"]) - gains_a = cap_auto["metadata"]["android.colorCorrection.gains"] - print "Auto gains:", gains_a - print "Auto transform:", xform_a - - # Manual capture 1: WB - req = its.objects.manual_capture_request(sens, exp) - req["android.colorCorrection.transform"] = xform_rat - req["android.colorCorrection.gains"] = gains - cap_man1 = cam.do_capture(req) - img_man1 = its.image.convert_capture_to_rgb_image(cap_man1) - its.image.write_image(img_man1, "%s_manual_wb.jpg" % (NAME)) - xform_m1 = its.objects.rational_to_float( - cap_man1["metadata"]["android.colorCorrection.transform"]) - gains_m1 = cap_man1["metadata"]["android.colorCorrection.gains"] - print "Manual wb gains:", gains_m1 - print "Manual wb transform:", xform_m1 - - # Manual capture 2: WB + tonemap - gamma = sum([[i/63.0,math.pow(i/63.0,1/2.2)] for i in xrange(64)],[]) - req["android.tonemap.mode"] = 0 - req["android.tonemap.curveRed"] = gamma - req["android.tonemap.curveGreen"] = gamma - req["android.tonemap.curveBlue"] = gamma - cap_man2 = cam.do_capture(req) - img_man2 = its.image.convert_capture_to_rgb_image(cap_man2) - its.image.write_image(img_man2, "%s_manual_wb_tm.jpg" % (NAME)) - xform_m2 = its.objects.rational_to_float( - cap_man2["metadata"]["android.colorCorrection.transform"]) - gains_m2 = cap_man2["metadata"]["android.colorCorrection.gains"] - print "Manual wb+tm gains:", gains_m2 - print "Manual wb+tm transform:", xform_m2 - - # Check that the WB gains and transform reported in each capture - # result match with the original AWB estimate from do_3a. - for g,x in [(gains_a,xform_a),(gains_m1,xform_m1),(gains_m2,xform_m2)]: - assert(all([abs(xform[i] - x[i]) < 0.05 for i in range(9)])) - assert(all([abs(gains[i] - g[i]) < 0.05 for i in range(4)])) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_black_white.py b/apps/CameraITS/tests/scene1/test_black_white.py deleted file mode 100644 index e471602..0000000 --- a/apps/CameraITS/tests/scene1/test_black_white.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that the device will produce full black+white images. - """ - NAME = os.path.basename(__file__).split(".")[0] - - r_means = [] - g_means = [] - b_means = [] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.manual_sensor(props): - print "Test skipped" - return - - expt_range = props['android.sensor.info.exposureTimeRange'] - sens_range = props['android.sensor.info.sensitivityRange'] - - # Take a shot with very low ISO and exposure time. Expect it to - # be black. - print "Black shot: sens = %d, exp time = %.4fms" % ( - sens_range[0], expt_range[0]/1000000.0) - req = its.objects.manual_capture_request(sens_range[0], expt_range[0]) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_black.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - black_means = its.image.compute_image_means(tile) - r_means.append(black_means[0]) - g_means.append(black_means[1]) - b_means.append(black_means[2]) - print "Dark pixel means:", black_means - - # Take a shot with very high ISO and exposure time. Expect it to - # be white. - print "White shot: sens = %d, exp time = %.2fms" % ( - sens_range[1], expt_range[1]/1000000.0) - req = its.objects.manual_capture_request(sens_range[1], expt_range[1]) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_white.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - white_means = its.image.compute_image_means(tile) - r_means.append(white_means[0]) - g_means.append(white_means[1]) - b_means.append(white_means[2]) - print "Bright pixel means:", white_means - - # Draw a plot. - pylab.plot([0,1], r_means, 'r') - pylab.plot([0,1], g_means, 'g') - pylab.plot([0,1], b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - for val in black_means: - assert(val < 0.025) - for val in white_means: - assert(val > 0.975) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py b/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py deleted file mode 100644 index 3858c0c..0000000 --- a/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import numpy - -def main(): - """Take long bursts of images and check that they're all identical. - - Assumes a static scene. Can be used to idenfity if there are sporadic - frames that are processed differently or have artifacts. Uses manual - capture settings. - """ - NAME = os.path.basename(__file__).split(".")[0] - - BURST_LEN = 50 - BURSTS = 5 - FRAMES = BURST_LEN * BURSTS - - SPREAD_THRESH = 0.03 - - with its.device.ItsSession() as cam: - - # Capture at the smallest resolution. - props = cam.get_camera_properties() - if not its.caps.manual_sensor(props): - print "Test skipped" - return - - _, fmt = its.objects.get_fastest_manual_capture_settings(props) - e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"] - req = its.objects.manual_capture_request(s, e) - w,h = fmt["width"], fmt["height"] - - # Capture bursts of YUV shots. - # Get the mean values of a center patch for each. - # Also build a 4D array, which is an array of all RGB images. - r_means = [] - g_means = [] - b_means = [] - imgs = numpy.empty([FRAMES,h,w,3]) - for j in range(BURSTS): - caps = cam.do_capture([req]*BURST_LEN, [fmt]) - for i,cap in enumerate(caps): - n = j*BURST_LEN + i - imgs[n] = its.image.convert_capture_to_rgb_image(cap) - tile = its.image.get_image_patch(imgs[n], 0.45, 0.45, 0.1, 0.1) - means = its.image.compute_image_means(tile) - r_means.append(means[0]) - g_means.append(means[1]) - b_means.append(means[2]) - - # Dump all images. - print "Dumping images" - for i in range(FRAMES): - its.image.write_image(imgs[i], "%s_frame%03d.jpg"%(NAME,i)) - - # The mean image. - img_mean = imgs.mean(0) - its.image.write_image(img_mean, "%s_mean.jpg"%(NAME)) - - # Pass/fail based on center patch similarity. - for means in [r_means, g_means, b_means]: - spread = max(means) - min(means) - print spread - assert(spread < SPREAD_THRESH) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_capture_result.py b/apps/CameraITS/tests/scene1/test_capture_result.py deleted file mode 100644 index 304e811..0000000 --- a/apps/CameraITS/tests/scene1/test_capture_result.py +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import os.path -import numpy -import matplotlib.pyplot - -# Required for 3d plot to work -import mpl_toolkits.mplot3d - -def main(): - """Test that valid data comes back in CaptureResult objects. - """ - global NAME, auto_req, manual_req, w_map, h_map - global manual_tonemap, manual_transform, manual_gains, manual_region - global manual_exp_time, manual_sensitivity, manual_gains_ok - - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.manual_sensor(props) or - not its.caps.manual_post_proc(props)): - print "Test skipped" - return - - manual_tonemap = [0,0, 1,1] # Linear - manual_transform = its.objects.int_to_rational([1,2,3, 4,5,6, 7,8,9]) - manual_gains = [1,2,3,4] - manual_region = [{"x":8,"y":8,"width":128,"height":128,"weight":1}] - manual_exp_time = min(props['android.sensor.info.exposureTimeRange']) - manual_sensitivity = min(props['android.sensor.info.sensitivityRange']) - - # The camera HAL may not support different gains for two G channels. - manual_gains_ok = [[1,2,3,4],[1,2,2,4],[1,3,3,4]] - - auto_req = its.objects.auto_capture_request() - auto_req["android.statistics.lensShadingMapMode"] = 1 - - manual_req = { - "android.control.mode": 0, - "android.control.aeMode": 0, - "android.control.awbMode": 0, - "android.control.afMode": 0, - "android.sensor.frameDuration": 0, - "android.sensor.sensitivity": manual_sensitivity, - "android.sensor.exposureTime": manual_exp_time, - "android.colorCorrection.mode": 0, - "android.colorCorrection.transform": manual_transform, - "android.colorCorrection.gains": manual_gains, - "android.tonemap.mode": 0, - "android.tonemap.curveRed": manual_tonemap, - "android.tonemap.curveGreen": manual_tonemap, - "android.tonemap.curveBlue": manual_tonemap, - "android.control.aeRegions": manual_region, - "android.control.afRegions": manual_region, - "android.control.awbRegions": manual_region, - "android.statistics.lensShadingMapMode":1 - } - - w_map = props["android.lens.info.shadingMapSize"]["width"] - h_map = props["android.lens.info.shadingMapSize"]["height"] - - print "Testing auto capture results" - lsc_map_auto = test_auto(cam, w_map, h_map) - print "Testing manual capture results" - test_manual(cam, w_map, h_map, lsc_map_auto) - print "Testing auto capture results again" - test_auto(cam, w_map, h_map) - -# A very loose definition for two floats being close to each other; -# there may be different interpolation and rounding used to get the -# two values, and all this test is looking at is whether there is -# something obviously broken; it's not looking for a perfect match. -def is_close_float(n1, n2): - return abs(n1 - n2) < 0.05 - -def is_close_rational(n1, n2): - return is_close_float(its.objects.rational_to_float(n1), - its.objects.rational_to_float(n2)) - -def draw_lsc_plot(w_map, h_map, lsc_map, name): - for ch in range(4): - fig = matplotlib.pyplot.figure() - ax = fig.gca(projection='3d') - xs = numpy.array([range(w_map)] * h_map).reshape(h_map, w_map) - ys = numpy.array([[i]*w_map for i in range(h_map)]).reshape( - h_map, w_map) - zs = numpy.array(lsc_map[ch::4]).reshape(h_map, w_map) - ax.plot_wireframe(xs, ys, zs) - matplotlib.pyplot.savefig("%s_plot_lsc_%s_ch%d.png"%(NAME,name,ch)) - -def test_auto(cam, w_map, h_map): - # Get 3A lock first, so the auto values in the capture result are - # populated properly. - rect = [[0,0,1,1,1]] - cam.do_3a(rect, rect, rect, do_af=False) - - cap = cam.do_capture(auto_req) - cap_res = cap["metadata"] - - gains = cap_res["android.colorCorrection.gains"] - transform = cap_res["android.colorCorrection.transform"] - exp_time = cap_res['android.sensor.exposureTime'] - lsc_map = cap_res["android.statistics.lensShadingMap"] - ctrl_mode = cap_res["android.control.mode"] - - print "Control mode:", ctrl_mode - print "Gains:", gains - print "Transform:", [its.objects.rational_to_float(t) - for t in transform] - print "AE region:", cap_res['android.control.aeRegions'] - print "AF region:", cap_res['android.control.afRegions'] - print "AWB region:", cap_res['android.control.awbRegions'] - print "LSC map:", w_map, h_map, lsc_map[:8] - - assert(ctrl_mode == 1) - - # Color correction gain and transform must be valid. - assert(len(gains) == 4) - assert(len(transform) == 9) - assert(all([g > 0 for g in gains])) - assert(all([t["denominator"] != 0 for t in transform])) - - # Color correction should not match the manual settings. - assert(any([not is_close_float(gains[i], manual_gains[i]) - for i in xrange(4)])) - assert(any([not is_close_rational(transform[i], manual_transform[i]) - for i in xrange(9)])) - - # Exposure time must be valid. - assert(exp_time > 0) - - # Lens shading map must be valid. - assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map)) - assert(all([m >= 1 for m in lsc_map])) - - draw_lsc_plot(w_map, h_map, lsc_map, "auto") - - return lsc_map - -def test_manual(cam, w_map, h_map, lsc_map_auto): - cap = cam.do_capture(manual_req) - cap_res = cap["metadata"] - - gains = cap_res["android.colorCorrection.gains"] - transform = cap_res["android.colorCorrection.transform"] - curves = [cap_res["android.tonemap.curveRed"], - cap_res["android.tonemap.curveGreen"], - cap_res["android.tonemap.curveBlue"]] - exp_time = cap_res['android.sensor.exposureTime'] - lsc_map = cap_res["android.statistics.lensShadingMap"] - ctrl_mode = cap_res["android.control.mode"] - - print "Control mode:", ctrl_mode - print "Gains:", gains - print "Transform:", [its.objects.rational_to_float(t) - for t in transform] - print "Tonemap:", curves[0][1::16] - print "AE region:", cap_res['android.control.aeRegions'] - print "AF region:", cap_res['android.control.afRegions'] - print "AWB region:", cap_res['android.control.awbRegions'] - print "LSC map:", w_map, h_map, lsc_map[:8] - - assert(ctrl_mode == 0) - - # Color correction gain and transform must be valid. - # Color correction gains and transform should be the same size and - # values as the manually set values. - assert(len(gains) == 4) - assert(len(transform) == 9) - assert( all([is_close_float(gains[i], manual_gains_ok[0][i]) - for i in xrange(4)]) or - all([is_close_float(gains[i], manual_gains_ok[1][i]) - for i in xrange(4)]) or - all([is_close_float(gains[i], manual_gains_ok[2][i]) - for i in xrange(4)])) - assert(all([is_close_rational(transform[i], manual_transform[i]) - for i in xrange(9)])) - - # Tonemap must be valid. - # The returned tonemap must be linear. - for c in curves: - assert(len(c) > 0) - assert(all([is_close_float(c[i], c[i+1]) - for i in xrange(0,len(c),2)])) - - # Exposure time must be close to the requested exposure time. - assert(is_close_float(exp_time/1000000.0, manual_exp_time/1000000.0)) - - # Lens shading map must be valid. - assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map)) - assert(all([m >= 1 for m in lsc_map])) - - draw_lsc_plot(w_map, h_map, lsc_map, "manual") - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_crop_region_raw.py b/apps/CameraITS/tests/scene1/test_crop_region_raw.py deleted file mode 100644 index 94c8e2b..0000000 --- a/apps/CameraITS/tests/scene1/test_crop_region_raw.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import numpy -import os.path - -def main(): - """Test that raw streams are not croppable. - """ - NAME = os.path.basename(__file__).split(".")[0] - - DIFF_THRESH = 0.05 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.compute_target_exposure(props) or - not its.caps.raw16(props)): - print "Test skipped" - return - - a = props['android.sensor.info.activeArraySize'] - ax, ay = a["left"], a["top"] - aw, ah = a["right"] - a["left"], a["bottom"] - a["top"] - print "Active sensor region: (%d,%d %dx%d)" % (ax, ay, aw, ah) - - # Capture without a crop region. - # Use a manual request with a linear tonemap so that the YUV and RAW - # should look the same (once converted by the its.image module). - e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"] - req = its.objects.manual_capture_request(s,e, True) - cap1_raw, cap1_yuv = cam.do_capture(req, cam.CAP_RAW_YUV) - - # Capture with a center crop region. - req["android.scaler.cropRegion"] = { - "top": ay + ah/3, - "left": ax + aw/3, - "right": ax + 2*aw/3, - "bottom": ay + 2*ah/3} - cap2_raw, cap2_yuv = cam.do_capture(req, cam.CAP_RAW_YUV) - - reported_crops = [] - imgs = {} - for s,cap in [("yuv_full",cap1_yuv), ("raw_full",cap1_raw), - ("yuv_crop",cap2_yuv), ("raw_crop",cap2_raw)]: - img = its.image.convert_capture_to_rgb_image(cap, props=props) - its.image.write_image(img, "%s_%s.jpg" % (NAME, s)) - r = cap["metadata"]["android.scaler.cropRegion"] - x, y = a["left"], a["top"] - w, h = a["right"] - a["left"], a["bottom"] - a["top"] - reported_crops.append((x,y,w,h)) - imgs[s] = img - print "Crop on %s: (%d,%d %dx%d)" % (s, x,y,w,h) - - # The metadata should report uncropped for all shots (since there is - # at least 1 uncropped stream in each case). - for (x,y,w,h) in reported_crops: - assert((ax,ay,aw,ah) == (x,y,w,h)) - - # Also check the image content; 3 of the 4 shots should match. - # Note that all the shots are RGB below; the variable names correspond - # to what was captured. - # Average the images down 4x4 -> 1 prior to comparison to smooth out - # noise. - # Shrink the YUV images an additional 2x2 -> 1 to account for the size - # reduction that the raw images went through in the RGB conversion. - imgs2 = {} - for s,img in imgs.iteritems(): - h,w,ch = img.shape - m = 4 - if s in ["yuv_full", "yuv_crop"]: - m = 8 - img = img.reshape(h/m,m,w/m,m,3).mean(3).mean(1).reshape(h/m,w/m,3) - imgs2[s] = img - print s, img.shape - - # Strip any border pixels from the raw shots (since the raw images may - # be larger than the YUV images). Assume a symmetric padded border. - xpad = (imgs2["raw_full"].shape[1] - imgs2["yuv_full"].shape[1]) / 2 - ypad = (imgs2["raw_full"].shape[0] - imgs2["yuv_full"].shape[0]) / 2 - wyuv = imgs2["yuv_full"].shape[1] - hyuv = imgs2["yuv_full"].shape[0] - imgs2["raw_full"]=imgs2["raw_full"][ypad:ypad+hyuv:,xpad:xpad+wyuv:,::] - imgs2["raw_crop"]=imgs2["raw_crop"][ypad:ypad+hyuv:,xpad:xpad+wyuv:,::] - print "Stripping padding before comparison:", xpad, ypad - - for s,img in imgs2.iteritems(): - its.image.write_image(img, "%s_comp_%s.jpg" % (NAME, s)) - - # Compute image diffs. - diff_yuv = numpy.fabs((imgs2["yuv_full"] - imgs2["yuv_crop"])).mean() - diff_raw = numpy.fabs((imgs2["raw_full"] - imgs2["raw_crop"])).mean() - print "YUV diff (crop vs. non-crop):", diff_yuv - print "RAW diff (crop vs. non-crop):", diff_raw - - assert(diff_yuv > DIFF_THRESH) - assert(diff_raw < DIFF_THRESH) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_crop_regions.py b/apps/CameraITS/tests/scene1/test_crop_regions.py deleted file mode 100644 index da0cd0a..0000000 --- a/apps/CameraITS/tests/scene1/test_crop_regions.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import numpy - -def main(): - """Test that crop regions work. - """ - NAME = os.path.basename(__file__).split(".")[0] - - # A list of 5 regions, specified in normalized (x,y,w,h) coords. - # The regions correspond to: TL, TR, BL, BR, CENT - REGIONS = [(0.0, 0.0, 0.5, 0.5), - (0.5, 0.0, 0.5, 0.5), - (0.0, 0.5, 0.5, 0.5), - (0.5, 0.5, 0.5, 0.5), - (0.25, 0.25, 0.5, 0.5)] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - a = props['android.sensor.info.activeArraySize'] - ax, ay = a["left"], a["top"] - aw, ah = a["right"] - a["left"], a["bottom"] - a["top"] - e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"] - print "Active sensor region (%d,%d %dx%d)" % (ax, ay, aw, ah) - - # Uses a 2x digital zoom. - assert(props['android.scaler.availableMaxDigitalZoom'] >= 2) - - # Capture a full frame. - req = its.objects.manual_capture_request(s,e) - cap_full = cam.do_capture(req) - img_full = its.image.convert_capture_to_rgb_image(cap_full) - its.image.write_image(img_full, "%s_full.jpg" % (NAME)) - wfull, hfull = cap_full["width"], cap_full["height"] - - # Capture a burst of crop region frames. - # Note that each region is 1/2x1/2 of the full frame, and is digitally - # zoomed into the full size output image, so must be downscaled (below) - # by 2x when compared to a tile of the full image. - reqs = [] - for x,y,w,h in REGIONS: - req = its.objects.manual_capture_request(s,e) - req["android.scaler.cropRegion"] = { - "top": int(ah * y), - "left": int(aw * x), - "right": int(aw * (x + w)), - "bottom": int(ah * (y + h))} - reqs.append(req) - caps_regions = cam.do_capture(reqs) - match_failed = False - for i,cap in enumerate(caps_regions): - a = cap["metadata"]["android.scaler.cropRegion"] - ax, ay = a["left"], a["top"] - aw, ah = a["right"] - a["left"], a["bottom"] - a["top"] - - # Match this crop image against each of the five regions of - # the full image, to find the best match (which should be - # the region that corresponds to this crop image). - img_crop = its.image.convert_capture_to_rgb_image(cap) - img_crop = its.image.downscale_image(img_crop, 2) - its.image.write_image(img_crop, "%s_crop%d.jpg" % (NAME, i)) - min_diff = None - min_diff_region = None - for j,(x,y,w,h) in enumerate(REGIONS): - tile_full = its.image.get_image_patch(img_full, x,y,w,h) - wtest = min(tile_full.shape[1], aw) - htest = min(tile_full.shape[0], ah) - tile_full = tile_full[0:htest:, 0:wtest:, ::] - tile_crop = img_crop[0:htest:, 0:wtest:, ::] - its.image.write_image(tile_full, "%s_fullregion%d.jpg"%(NAME,j)) - diff = numpy.fabs(tile_full - tile_crop).mean() - if min_diff is None or diff < min_diff: - min_diff = diff - min_diff_region = j - if i != min_diff_region: - match_failed = True - print "Crop image %d (%d,%d %dx%d) best match with region %d"%( - i, ax, ay, aw, ah, min_diff_region) - - assert(not match_failed) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py deleted file mode 100644 index 8676358..0000000 --- a/apps/CameraITS/tests/scene1/test_exposure.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import numpy -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that a constant exposure is seen as ISO and exposure time vary. - - Take a series of shots that have ISO and exposure time chosen to balance - each other; result should be the same brightness, but over the sequence - the images should get noisier. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_OUTLIER_DIFF = 0.1 - THRESHOLD_MIN_LEVEL = 0.1 - THRESHOLD_MAX_LEVEL = 0.9 - THRESHOLD_MAX_ABS_GRAD = 0.001 - - mults = [] - r_means = [] - g_means = [] - b_means = [] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - e,s = its.target.get_target_exposure_combos(cam)["minSensitivity"] - expt_range = props['android.sensor.info.exposureTimeRange'] - sens_range = props['android.sensor.info.sensitivityRange'] - - m = 1 - while s*m < sens_range[1] and e/m > expt_range[0]: - mults.append(m) - req = its.objects.manual_capture_request(s*m, e/m) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_mult=%02d.jpg" % (NAME, m)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - m = m + 4 - - # Draw a plot. - pylab.plot(mults, r_means, 'r') - pylab.plot(mults, g_means, 'g') - pylab.plot(mults, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - # Check for linearity. For each R,G,B channel, fit a line y=mx+b, and - # assert that the gradient is close to 0 (flat) and that there are no - # crazy outliers. Also ensure that the images aren't clamped to 0 or 1 - # (which would make them look like flat lines). - for chan in xrange(3): - values = [r_means, g_means, b_means][chan] - m, b = numpy.polyfit(mults, values, 1).tolist() - print "Channel %d line fit (y = mx+b): m = %f, b = %f" % (chan, m, b) - assert(abs(m) < THRESHOLD_MAX_ABS_GRAD) - assert(b > THRESHOLD_MIN_LEVEL and b < THRESHOLD_MAX_LEVEL) - for v in values: - assert(v > THRESHOLD_MIN_LEVEL and v < THRESHOLD_MAX_LEVEL) - assert(abs(v - b) < THRESHOLD_MAX_OUTLIER_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_format_combos.py b/apps/CameraITS/tests/scene1/test_format_combos.py deleted file mode 100644 index a021102..0000000 --- a/apps/CameraITS/tests/scene1/test_format_combos.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.error -import its.target -import sys -import os -import os.path - -# Change this to True, to have the test break at the first failure. -stop_at_first_failure = False - -def main(): - """Test different combinations of output formats. - """ - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - - props = cam.get_camera_properties() - if (not its.caps.compute_target_exposure(props) or - not its.caps.raw16(props)): - print "Test skipped" - return - - successes = [] - failures = [] - - # Two different requests: auto, and manual. - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req_aut = its.objects.auto_capture_request() - req_man = its.objects.manual_capture_request(s, e) - reqs = [req_aut, # R0 - req_man] # R1 - - # 10 different combos of output formats; some are single surfaces, and - # some are multiple surfaces. - wyuv,hyuv = its.objects.get_available_output_sizes("yuv", props)[-1] - wjpg,hjpg = its.objects.get_available_output_sizes("jpg", props)[-1] - fmt_yuv_prev = {"format":"yuv", "width":wyuv, "height":hyuv} - fmt_yuv_full = {"format":"yuv"} - fmt_jpg_prev = {"format":"jpeg","width":wjpg, "height":hjpg} - fmt_jpg_full = {"format":"jpeg"} - fmt_raw_full = {"format":"raw"} - fmt_combos =[ - [fmt_yuv_prev], # F0 - [fmt_yuv_full], # F1 - [fmt_jpg_prev], # F2 - [fmt_jpg_full], # F3 - [fmt_raw_full], # F4 - [fmt_yuv_prev, fmt_jpg_prev], # F5 - [fmt_yuv_prev, fmt_jpg_full], # F6 - [fmt_yuv_prev, fmt_raw_full], # F7 - [fmt_yuv_prev, fmt_jpg_prev, fmt_raw_full], # F8 - [fmt_yuv_prev, fmt_jpg_full, fmt_raw_full]] # F9 - - # Two different burst lengths: single frame, and 3 frames. - burst_lens = [1, # B0 - 3] # B1 - - # There are 2x10x2=40 different combinations. Run through them all. - n = 0 - for r,req in enumerate(reqs): - for f,fmt_combo in enumerate(fmt_combos): - for b,burst_len in enumerate(burst_lens): - try: - caps = cam.do_capture([req]*burst_len, fmt_combo) - successes.append((n,r,f,b)) - print "==> Success[%02d]: R%d F%d B%d" % (n,r,f,b) - - # Dump the captures out to jpegs. - if not isinstance(caps, list): - caps = [caps] - elif isinstance(caps[0], list): - caps = sum(caps, []) - for c,cap in enumerate(caps): - img = its.image.convert_capture_to_rgb_image(cap, - props=props) - its.image.write_image(img, - "%s_n%02d_r%d_f%d_b%d_c%d.jpg"%(NAME,n,r,f,b,c)) - - except Exception as e: - print e - print "==> Failure[%02d]: R%d F%d B%d" % (n,r,f,b) - failures.append((n,r,f,b)) - if stop_at_first_failure: - sys.exit(0) - n += 1 - - num_fail = len(failures) - num_success = len(successes) - num_total = len(reqs)*len(fmt_combos)*len(burst_lens) - num_not_run = num_total - num_success - num_fail - - print "\nFailures (%d / %d):" % (num_fail, num_total) - for (n,r,f,b) in failures: - print " %02d: R%d F%d B%d" % (n,r,f,b) - print "\nSuccesses (%d / %d):" % (num_success, num_total) - for (n,r,f,b) in successes: - print " %02d: R%d F%d B%d" % (n,r,f,b) - if num_not_run > 0: - print "\nNumber of tests not run: %d / %d" % (num_not_run, num_total) - print "" - - # The test passes if all the combinations successfully capture. - assert(num_fail == 0) - assert(num_success == num_total) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_jpeg.py b/apps/CameraITS/tests/scene1/test_jpeg.py deleted file mode 100644 index bc2d64e..0000000 --- a/apps/CameraITS/tests/scene1/test_jpeg.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import math - -def main(): - """Test that converted YUV images and device JPEG images look the same. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_RMS_DIFF = 0.01 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req = its.objects.manual_capture_request(s, e, True) - - # YUV - size = its.objects.get_available_output_sizes("yuv", props)[0] - out_surface = {"width":size[0], "height":size[1], "format":"yuv"} - cap = cam.do_capture(req, out_surface) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_fmt=yuv.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb0 = its.image.compute_image_means(tile) - - # JPEG - size = its.objects.get_available_output_sizes("jpg", props)[0] - out_surface = {"width":size[0], "height":size[1], "format":"jpg"} - cap = cam.do_capture(req, out_surface) - img = its.image.decompress_jpeg_to_rgb_image(cap["data"]) - its.image.write_image(img, "%s_fmt=jpg.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb1 = its.image.compute_image_means(tile) - - rms_diff = math.sqrt( - sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0) - print "RMS difference:", rms_diff - assert(rms_diff < THRESHOLD_MAX_RMS_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py deleted file mode 100644 index bef41ac..0000000 --- a/apps/CameraITS/tests/scene1/test_latching.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that settings latch on the right frame. - - Takes a bunch of shots using back-to-back requests, varying the capture - request parameters between shots. Checks that the images that come back - have the expected properties. - """ - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.full(props): - print "Test skipped" - return - - _,fmt = its.objects.get_fastest_manual_capture_settings(props) - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - e /= 2.0 - - r_means = [] - g_means = [] - b_means = [] - - reqs = [ - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s*2,e, True), - its.objects.manual_capture_request(s*2,e, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s, e*2, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s*2,e, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s, e*2, True), - its.objects.manual_capture_request(s, e, True), - its.objects.manual_capture_request(s, e*2, True), - its.objects.manual_capture_request(s, e*2, True), - ] - - caps = cam.do_capture(reqs, fmt) - for i,cap in enumerate(caps): - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_i=%02d.jpg" % (NAME, i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - - # Draw a plot. - idxs = range(len(r_means)) - pylab.plot(idxs, r_means, 'r') - pylab.plot(idxs, g_means, 'g') - pylab.plot(idxs, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - g_avg = sum(g_means) / len(g_means) - g_ratios = [g / g_avg for g in g_means] - g_hilo = [g>1.0 for g in g_ratios] - assert(g_hilo == [False, False, True, True, False, False, True, - False, True, False, True, False, True, True]) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_linearity.py b/apps/CameraITS/tests/scene1/test_linearity.py deleted file mode 100644 index fed0324..0000000 --- a/apps/CameraITS/tests/scene1/test_linearity.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import numpy -import math -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that device processing can be inverted to linear pixels. - - Captures a sequence of shots with the device pointed at a uniform - target. Attempts to invert all the ISP processing to get back to - linear R,G,B pixel data. - """ - NAME = os.path.basename(__file__).split(".")[0] - - RESIDUAL_THRESHOLD = 0.00005 - - # The HAL3.2 spec requires that curves up to 64 control points in length - # must be supported. - L = 64 - LM1 = float(L-1) - - gamma_lut = numpy.array( - sum([[i/LM1, math.pow(i/LM1, 1/2.2)] for i in xrange(L)], [])) - inv_gamma_lut = numpy.array( - sum([[i/LM1, math.pow(i/LM1, 2.2)] for i in xrange(L)], [])) - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - e,s = its.target.get_target_exposure_combos(cam)["midSensitivity"] - s /= 2 - sens_range = props['android.sensor.info.sensitivityRange'] - sensitivities = [s*1.0/3.0, s*2.0/3.0, s, s*4.0/3.0, s*5.0/3.0] - sensitivities = [s for s in sensitivities - if s > sens_range[0] and s < sens_range[1]] - - req = its.objects.manual_capture_request(0, e) - req["android.blackLevel.lock"] = True - req["android.tonemap.mode"] = 0 - req["android.tonemap.curveRed"] = gamma_lut.tolist() - req["android.tonemap.curveGreen"] = gamma_lut.tolist() - req["android.tonemap.curveBlue"] = gamma_lut.tolist() - - r_means = [] - g_means = [] - b_means = [] - - for sens in sensitivities: - req["android.sensor.sensitivity"] = sens - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image( - img, "%s_sens=%04d.jpg" % (NAME, sens)) - img = its.image.apply_lut_to_image(img, inv_gamma_lut[1::2] * LM1) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - - pylab.plot(sensitivities, r_means, 'r') - pylab.plot(sensitivities, g_means, 'g') - pylab.plot(sensitivities, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - # Check that each plot is actually linear. - for means in [r_means, g_means, b_means]: - line,residuals,_,_,_ = numpy.polyfit(range(5),means,1,full=True) - print "Line: m=%f, b=%f, resid=%f"%(line[0], line[1], residuals[0]) - assert(residuals[0] < RESIDUAL_THRESHOLD) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_locked_burst.py b/apps/CameraITS/tests/scene1/test_locked_burst.py deleted file mode 100644 index 83cfa25..0000000 --- a/apps/CameraITS/tests/scene1/test_locked_burst.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2014 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 its.image -import its.device -import its.objects -import os.path -import numpy -import pylab -import matplotlib -import matplotlib.pyplot - -def main(): - """Test 3A lock + YUV burst (using auto settings). - - This is a test that is designed to pass even on limited devices that - don't have MANUAL_SENSOR or PER_FRAME_CONTROLS. (They must be able to - capture bursts with full res @ full frame rate to pass, however). - """ - NAME = os.path.basename(__file__).split(".")[0] - - BURST_LEN = 10 - SPREAD_THRESH = 0.005 - FPS_MAX_DIFF = 2.0 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - - # Converge 3A prior to capture. - cam.do_3a(do_af=False, lock_ae=True, lock_awb=True) - - # After 3A has converged, lock AE+AWB for the duration of the test. - req = its.objects.auto_capture_request() - req["android.control.awbLock"] = True - req["android.control.aeLock"] = True - - # Capture bursts of YUV shots. - # Get the mean values of a center patch for each. - r_means = [] - g_means = [] - b_means = [] - caps = cam.do_capture([req]*BURST_LEN) - for i,cap in enumerate(caps): - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_frame%d.jpg"%(NAME,i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - means = its.image.compute_image_means(tile) - r_means.append(means[0]) - g_means.append(means[1]) - b_means.append(means[2]) - - # Pass/fail based on center patch similarity. - for means in [r_means, g_means, b_means]: - spread = max(means) - min(means) - print "Patch mean spread", spread - assert(spread < SPREAD_THRESH) - - # Also ensure that the burst was at full frame rate. - fmt_code = 0x23 - configs = props['android.scaler.streamConfigurationMap']\ - ['availableStreamConfigurations'] - min_duration = None - for cfg in configs: - if cfg['format'] == fmt_code and cfg['input'] == False and \ - cfg['width'] == caps[0]["width"] and \ - cfg['height'] == caps[0]["height"]: - min_duration = cfg["minFrameDuration"] - assert(min_duration is not None) - tstamps = [c['metadata']['android.sensor.timestamp'] for c in caps] - deltas = [tstamps[i]-tstamps[i-1] for i in range(1,len(tstamps))] - actual_fps = 1.0 / (max(deltas) / 1000000000.0) - max_fps = 1.0 / (min_duration / 1000000000.0) - print "FPS measured %.1f, max advertized %.1f" %(actual_fps, max_fps) - assert(max_fps - FPS_MAX_DIFF <= actual_fps <= max_fps) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_color_correction.py b/apps/CameraITS/tests/scene1/test_param_color_correction.py deleted file mode 100644 index 82f2342..0000000 --- a/apps/CameraITS/tests/scene1/test_param_color_correction.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that the android.colorCorrection.* params are applied when set. - - Takes shots with different transform and gains values, and tests that - they look correspondingly different. The transform and gains are chosen - to make the output go redder or bluer. - - Uses a linear tonemap. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_DIFF = 0.1 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - # Baseline request - e, s = its.target.get_target_exposure_combos(cam)["midSensitivity"] - req = its.objects.manual_capture_request(s, e, True) - req["android.colorCorrection.mode"] = 0 - - # Transforms: - # 1. Identity - # 2. Identity - # 3. Boost blue - transforms = [its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,1]), - its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,1]), - its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,2])] - - # Gains: - # 1. Unit - # 2. Boost red - # 3. Unit - gains = [[1,1,1,1], [2,1,1,1], [1,1,1,1]] - - r_means = [] - g_means = [] - b_means = [] - - # Capture requests: - # 1. With unit gains, and identity transform. - # 2. With a higher red gain, and identity transform. - # 3. With unit gains, and a transform that boosts blue. - for i in range(len(transforms)): - req["android.colorCorrection.transform"] = transforms[i] - req["android.colorCorrection.gains"] = gains[i] - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_req=%d.jpg" % (NAME, i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - ratios = [rgb_means[0] / rgb_means[1], rgb_means[2] / rgb_means[1]] - print "Means = ", rgb_means, " Ratios =", ratios - - # Draw a plot. - domain = range(len(transforms)) - pylab.plot(domain, r_means, 'r') - pylab.plot(domain, g_means, 'g') - pylab.plot(domain, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - # Expect G0 == G1 == G2, R0 == 0.5*R1 == R2, B0 == B1 == 0.5*B2 - # Also need to ensure that the imasge is not clamped to white/black. - assert(all(g_means[i] > 0.2 and g_means[i] < 0.8 for i in xrange(3))) - assert(abs(g_means[1] - g_means[0]) < THRESHOLD_MAX_DIFF) - assert(abs(g_means[2] - g_means[1]) < THRESHOLD_MAX_DIFF) - assert(abs(r_means[2] - r_means[0]) < THRESHOLD_MAX_DIFF) - assert(abs(r_means[1] - 2.0 * r_means[0]) < THRESHOLD_MAX_DIFF) - assert(abs(b_means[1] - b_means[0]) < THRESHOLD_MAX_DIFF) - assert(abs(b_means[2] - 2.0 * b_means[0]) < THRESHOLD_MAX_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_exposure_time.py b/apps/CameraITS/tests/scene1/test_param_exposure_time.py deleted file mode 100644 index 390fd3c..0000000 --- a/apps/CameraITS/tests/scene1/test_param_exposure_time.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that the android.sensor.exposureTime parameter is applied. - """ - NAME = os.path.basename(__file__).split(".")[0] - - exp_times = [] - r_means = [] - g_means = [] - b_means = [] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - e,s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - for i,e_mult in enumerate([0.8, 0.9, 1.0, 1.1, 1.2]): - req = its.objects.manual_capture_request(s, e * e_mult, True) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image( - img, "%s_frame%d.jpg" % (NAME, i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - exp_times.append(e * e_mult) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - - # Draw a plot. - pylab.plot(exp_times, r_means, 'r') - pylab.plot(exp_times, g_means, 'g') - pylab.plot(exp_times, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - # Test for pass/fail: check that each shot is brighter than the previous. - for means in [r_means, g_means, b_means]: - for i in range(len(means)-1): - assert(means[i+1] > means[i]) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_flash_mode.py b/apps/CameraITS/tests/scene1/test_param_flash_mode.py deleted file mode 100644 index 6d1be4f..0000000 --- a/apps/CameraITS/tests/scene1/test_param_flash_mode.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path - -def main(): - """Test that the android.flash.mode parameter is applied. - """ - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - flash_modes_reported = [] - flash_states_reported = [] - g_means = [] - - # Manually set the exposure to be a little on the dark side, so that - # it should be obvious whether the flash fired or not, and use a - # linear tonemap. - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - e /= 4 - req = its.objects.manual_capture_request(s, e, True) - - for f in [0,1,2]: - req["android.flash.mode"] = f - cap = cam.do_capture(req) - flash_modes_reported.append(cap["metadata"]["android.flash.mode"]) - flash_states_reported.append(cap["metadata"]["android.flash.state"]) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_mode=%d.jpg" % (NAME, f)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb = its.image.compute_image_means(tile) - g_means.append(rgb[1]) - - assert(flash_modes_reported == [0,1,2]) - assert(flash_states_reported[0] not in [3,4]) - assert(flash_states_reported[1] in [3,4]) - assert(flash_states_reported[2] in [3,4]) - - print "G brightnesses:", g_means - assert(g_means[1] > g_means[0]) - assert(g_means[2] > g_means[0]) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py b/apps/CameraITS/tests/scene1/test_param_noise_reduction.py deleted file mode 100644 index 618f8a7..0000000 --- a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that the android.noiseReduction.mode param is applied when set. - - Capture images with the camera dimly lit. Uses a high analog gain to - ensure the captured image is noisy. - - Captures three images, for NR off, "fast", and "high quality". - Also captures an image with low gain and NR off, and uses the variance - of this as the baseline. - """ - NAME = os.path.basename(__file__).split(".")[0] - - # List of variances for Y,U,V. - variances = [[],[],[]] - - # Reference (baseline) variance for each of Y,U,V. - ref_variance = [] - - nr_modes_reported = [] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - # NR mode 0 with low gain - e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"] - req = its.objects.manual_capture_request(s, e) - req["android.noiseReduction.mode"] = 0 - cap = cam.do_capture(req) - its.image.write_image( - its.image.convert_capture_to_rgb_image(cap), - "%s_low_gain.jpg" % (NAME)) - planes = its.image.convert_capture_to_planes(cap) - for j in range(3): - img = planes[j] - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - ref_variance.append(its.image.compute_image_variances(tile)[0]) - print "Ref variances:", ref_variance - - for i in range(3): - # NR modes 0, 1, 2 with high gain - e, s = its.target.get_target_exposure_combos(cam)["maxSensitivity"] - req = its.objects.manual_capture_request(s, e) - req["android.noiseReduction.mode"] = i - cap = cam.do_capture(req) - nr_modes_reported.append( - cap["metadata"]["android.noiseReduction.mode"]) - its.image.write_image( - its.image.convert_capture_to_rgb_image(cap), - "%s_high_gain_nr=%d.jpg" % (NAME, i)) - planes = its.image.convert_capture_to_planes(cap) - for j in range(3): - img = planes[j] - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - variance = its.image.compute_image_variances(tile)[0] - variances[j].append(variance / ref_variance[j]) - print "Variances with NR mode [0,1,2]:", variances - - # Draw a plot. - for j in range(3): - pylab.plot(range(3), variances[j], "rgb"[j]) - matplotlib.pyplot.savefig("%s_plot_variances.png" % (NAME)) - - assert(nr_modes_reported == [0,1,2]) - - # Check that the variance of the NR=0 image is higher than for the - # NR=1 and NR=2 images. - for j in range(3): - for i in range(1,3): - assert(variances[j][i] < variances[j][0]) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_sensitivity.py b/apps/CameraITS/tests/scene1/test_param_sensitivity.py deleted file mode 100644 index c26e9f9..0000000 --- a/apps/CameraITS/tests/scene1/test_param_sensitivity.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import pylab -import os.path -import matplotlib -import matplotlib.pyplot - -def main(): - """Test that the android.sensor.sensitivity parameter is applied. - """ - NAME = os.path.basename(__file__).split(".")[0] - - NUM_STEPS = 5 - - sensitivities = None - r_means = [] - g_means = [] - b_means = [] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - expt,_ = its.target.get_target_exposure_combos(cam)["midSensitivity"] - sens_range = props['android.sensor.info.sensitivityRange'] - sens_step = (sens_range[1] - sens_range[0]) / float(NUM_STEPS-1) - sensitivities = [sens_range[0] + i * sens_step for i in range(NUM_STEPS)] - - for s in sensitivities: - req = its.objects.manual_capture_request(s, expt) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image( - img, "%s_iso=%04d.jpg" % (NAME, s)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means = its.image.compute_image_means(tile) - r_means.append(rgb_means[0]) - g_means.append(rgb_means[1]) - b_means.append(rgb_means[2]) - - # Draw a plot. - pylab.plot(sensitivities, r_means, 'r') - pylab.plot(sensitivities, g_means, 'g') - pylab.plot(sensitivities, b_means, 'b') - pylab.ylim([0,1]) - matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME)) - - # Test for pass/fail: check that each shot is brighter than the previous. - for means in [r_means, g_means, b_means]: - for i in range(len(means)-1): - assert(means[i+1] > means[i]) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py deleted file mode 100644 index fbd452c..0000000 --- a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os -import os.path - -def main(): - """Test that the android.tonemap.mode param is applied. - - Applies different tonemap curves to each R,G,B channel, and checks - that the output images are modified as expected. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_RATIO_MIN_DIFF = 0.1 - THRESHOLD_DIFF_MAX_DIFF = 0.05 - - # The HAL3.2 spec requires that curves up to 64 control points in length - # must be supported. - L = 32 - LM1 = float(L-1) - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - e /= 2 - - # Test 1: that the tonemap curves have the expected effect. Take two - # shots, with n in [0,1], where each has a linear tonemap, with the - # n=1 shot having a steeper gradient. The gradient for each R,G,B - # channel increases (i.e.) R[n=1] should be brighter than R[n=0], - # and G[n=1] should be brighter than G[n=0] by a larger margin, etc. - rgb_means = [] - - for n in [0,1]: - req = its.objects.manual_capture_request(s,e) - req["android.tonemap.mode"] = 0 - req["android.tonemap.curveRed"] = ( - sum([[i/LM1, min(1.0,(1+0.5*n)*i/LM1)] for i in range(L)], [])) - req["android.tonemap.curveGreen"] = ( - sum([[i/LM1, min(1.0,(1+1.0*n)*i/LM1)] for i in range(L)], [])) - req["android.tonemap.curveBlue"] = ( - sum([[i/LM1, min(1.0,(1+1.5*n)*i/LM1)] for i in range(L)], [])) - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image( - img, "%s_n=%d.jpg" %(NAME, n)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means.append(its.image.compute_image_means(tile)) - - rgb_ratios = [rgb_means[1][i] / rgb_means[0][i] for i in xrange(3)] - print "Test 1: RGB ratios:", rgb_ratios - assert(rgb_ratios[0] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[1]) - assert(rgb_ratios[1] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[2]) - - - # Test 2: that the length of the tonemap curve (i.e. number of control - # points) doesn't affect the output. - rgb_means = [] - - for size in [32,64]: - m = float(size-1) - curve = sum([[i/m, i/m] for i in range(size)], []) - req = its.objects.manual_capture_request(s,e) - req["android.tonemap.mode"] = 0 - req["android.tonemap.curveRed"] = curve - req["android.tonemap.curveGreen"] = curve - req["android.tonemap.curveBlue"] = curve - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image( - img, "%s_size=%02d.jpg" %(NAME, size)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb_means.append(its.image.compute_image_means(tile)) - - rgb_diffs = [rgb_means[1][i] - rgb_means[0][i] for i in xrange(3)] - print "Test 2: RGB diffs:", rgb_diffs - assert(abs(rgb_diffs[0]) < THRESHOLD_DIFF_MAX_DIFF) - assert(abs(rgb_diffs[1]) < THRESHOLD_DIFF_MAX_DIFF) - assert(abs(rgb_diffs[2]) < THRESHOLD_DIFF_MAX_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py deleted file mode 100644 index bf0e2ea..0000000 --- a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2014 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 its.device -import its.caps -import its.objects -import its.image -import os.path -import pylab -import matplotlib -import matplotlib.pyplot - -def main(): - """Capture a set of raw images with increasing gains and measure the noise. - - Capture raw-only, in a burst. - """ - NAME = os.path.basename(__file__).split(".")[0] - - # Each shot must be 1% noisier (by the variance metric) than the previous - # one. - VAR_THRESH = 1.01 - - NUM_STEPS = 5 - - with its.device.ItsSession() as cam: - - props = cam.get_camera_properties() - if not its.caps.raw16(props) or \ - not its.caps.manual_sensor(props) or \ - not its.caps.read_3a(props): - print "Test skipped" - return - - # Expose for the scene with min sensitivity - sens_min, sens_max = props['android.sensor.info.sensitivityRange'] - sens_step = (sens_max - sens_min) / NUM_STEPS - s_ae,e_ae,_,_,_ = cam.do_3a(get_results=True) - s_e_prod = s_ae * e_ae - - reqs = [] - settings = [] - for s in range(sens_min, sens_max, sens_step): - e = int(s_e_prod / float(s)) - req = its.objects.manual_capture_request(s, e) - reqs.append(req) - settings.append((s,e)) - - caps = cam.do_capture(reqs, cam.CAP_RAW) - - variances = [] - for i,cap in enumerate(caps): - (s,e) = settings[i] - - # Measure the variance. Each shot should be noisier than the - # previous shot (as the gain is increasing). - plane = its.image.convert_capture_to_planes(cap, props)[1] - tile = its.image.get_image_patch(plane, 0.45,0.45,0.1,0.1) - var = its.image.compute_image_variances(tile)[0] - variances.append(var) - - img = its.image.convert_capture_to_rgb_image(cap, props=props) - its.image.write_image(img, "%s_s=%05d_var=%f.jpg" % (NAME,s,var)) - print "s=%d, e=%d, var=%e"%(s,e,var) - - pylab.plot(range(len(variances)), variances) - matplotlib.pyplot.savefig("%s_variances.png" % (NAME)) - - # Test that each shot is noisier than the previous one. - for i in range(len(variances) - 1): - assert(variances[i] < variances[i+1] / VAR_THRESH) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py deleted file mode 100644 index 8e36219..0000000 --- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2014 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 its.device -import its.caps -import its.objects -import its.image -import os.path -import pylab -import matplotlib -import matplotlib.pyplot - -def main(): - """Capture a set of raw images with increasing gains and measure the noise. - """ - NAME = os.path.basename(__file__).split(".")[0] - - # Each shot must be 1% noisier (by the variance metric) than the previous - # one. - VAR_THRESH = 1.01 - - NUM_STEPS = 5 - - with its.device.ItsSession() as cam: - - props = cam.get_camera_properties() - if (not its.caps.raw16(props) or - not its.caps.manual_sensor(props) or - not its.caps.read_3a(props)): - print "Test skipped" - return - - # Expose for the scene with min sensitivity - sens_min, sens_max = props['android.sensor.info.sensitivityRange'] - sens_step = (sens_max - sens_min) / NUM_STEPS - s_ae,e_ae,_,_,_ = cam.do_3a(get_results=True) - s_e_prod = s_ae * e_ae - - variances = [] - for s in range(sens_min, sens_max, sens_step): - - e = int(s_e_prod / float(s)) - req = its.objects.manual_capture_request(s, e) - - # Capture raw+yuv, but only look at the raw. - cap,_ = cam.do_capture(req, cam.CAP_RAW_YUV) - - # Measure the variance. Each shot should be noisier than the - # previous shot (as the gain is increasing). - plane = its.image.convert_capture_to_planes(cap, props)[1] - tile = its.image.get_image_patch(plane, 0.45,0.45,0.1,0.1) - var = its.image.compute_image_variances(tile)[0] - variances.append(var) - - img = its.image.convert_capture_to_rgb_image(cap, props=props) - its.image.write_image(img, "%s_s=%05d_var=%f.jpg" % (NAME,s,var)) - print "s=%d, e=%d, var=%e"%(s,e,var) - - pylab.plot(range(len(variances)), variances) - matplotlib.pyplot.savefig("%s_variances.png" % (NAME)) - - # Test that each shot is noisier than the previous one. - for i in range(len(variances) - 1): - assert(variances[i] < variances[i+1] / VAR_THRESH) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py deleted file mode 100644 index 7af51c5..0000000 --- a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import os.path -import numpy - -def main(): - """Test a sequence of shots with different tonemap curves. - """ - NAME = os.path.basename(__file__).split(".")[0] - - # There should be 3 identical frames followed by a different set of - # 3 identical frames. - MAX_SAME_DELTA = 0.01 - MIN_DIFF_DELTA = 0.10 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.manual_sensor(props) or - not its.caps.manual_post_proc(props)): - print "Test skipped" - return - - sens, exp_time, _,_,_ = cam.do_3a(do_af=False,get_results=True) - - means = [] - - # Capture 3 manual shots with a linear tonemap. - req = its.objects.manual_capture_request(sens, exp_time, True) - for i in [0,1,2]: - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - means.append(tile.mean(0).mean(0)) - - # Capture 3 manual shots with the default tonemap. - req = its.objects.manual_capture_request(sens, exp_time, False) - for i in [3,4,5]: - cap = cam.do_capture(req) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - means.append(tile.mean(0).mean(0)) - - # Compute the delta between each consecutive frame pair. - deltas = [numpy.max(numpy.fabs(means[i+1]-means[i])) \ - for i in range(len(means)-1)] - print "Deltas between consecutive frames:", deltas - - assert(all([abs(deltas[i]) < MAX_SAME_DELTA for i in [0,1,3,4]])) - assert(abs(deltas[2]) > MIN_DIFF_DELTA) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py deleted file mode 100644 index 2367ca2..0000000 --- a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2013 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import math - -def main(): - """Test that the reported sizes and formats for image capture work. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_RMS_DIFF = 0.03 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - # Use a manual request with a linear tonemap so that the YUV and JPEG - # should look the same (once converted by the its.image module). - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req = its.objects.manual_capture_request(s, e, True) - - rgbs = [] - - for size in its.objects.get_available_output_sizes("yuv", props): - out_surface = {"width":size[0], "height":size[1], "format":"yuv"} - cap = cam.do_capture(req, out_surface) - assert(cap["format"] == "yuv") - assert(cap["width"] == size[0]) - assert(cap["height"] == size[1]) - print "Captured YUV %dx%d" % (cap["width"], cap["height"]) - img = its.image.convert_capture_to_rgb_image(cap) - its.image.write_image(img, "%s_yuv_w%d_h%d.jpg"%( - NAME,size[0],size[1])) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb = its.image.compute_image_means(tile) - rgbs.append(rgb) - - for size in its.objects.get_available_output_sizes("jpg", props): - out_surface = {"width":size[0], "height":size[1], "format":"jpg"} - cap = cam.do_capture(req, out_surface) - assert(cap["format"] == "jpeg") - assert(cap["width"] == size[0]) - assert(cap["height"] == size[1]) - img = its.image.decompress_jpeg_to_rgb_image(cap["data"]) - its.image.write_image(img, "%s_jpg_w%d_h%d.jpg"%( - NAME,size[0], size[1])) - assert(img.shape[0] == size[1]) - assert(img.shape[1] == size[0]) - assert(img.shape[2] == 3) - print "Captured JPEG %dx%d" % (cap["width"], cap["height"]) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb = its.image.compute_image_means(tile) - rgbs.append(rgb) - - max_diff = 0 - rgb0 = rgbs[0] - for rgb1 in rgbs[1:]: - rms_diff = math.sqrt( - sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0) - max_diff = max(max_diff, rms_diff) - print "Max RMS difference:", max_diff - assert(rms_diff < THRESHOLD_MAX_RMS_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py b/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py deleted file mode 100644 index 4924c7b..0000000 --- a/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import os.path - -def main(): - """Test capturing a single frame as both DNG and YUV outputs. - """ - NAME = os.path.basename(__file__).split(".")[0] - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.raw(props) or - not its.caps.read_3a(props)): - print "Test skipped" - return - - cam.do_3a() - - req = its.objects.auto_capture_request() - cap_dng, cap_yuv = cam.do_capture(req, cam.CAP_DNG_YUV) - - img = its.image.convert_capture_to_rgb_image(cap_yuv) - its.image.write_image(img, "%s.jpg" % (NAME)) - - with open("%s.dng"%(NAME), "wb") as f: - f.write(cap_dng["data"]) - - # No specific pass/fail check; test is assumed to have succeeded if - # it completes. - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py deleted file mode 100644 index 15aa17c..0000000 --- a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import math - -def main(): - """Test capturing a single frame as both YUV and JPEG outputs. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_RMS_DIFF = 0.01 - - fmt_yuv = {"format":"yuv"} - fmt_jpeg = {"format":"jpeg"} - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if not its.caps.compute_target_exposure(props): - print "Test skipped" - return - - # Use a manual request with a linear tonemap so that the YUV and JPEG - # should look the same (once converted by the its.image module). - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req = its.objects.manual_capture_request(s, e, True) - - cap_yuv, cap_jpeg = cam.do_capture(req, [fmt_yuv, fmt_jpeg]) - - img = its.image.convert_capture_to_rgb_image(cap_yuv, True) - its.image.write_image(img, "%s_yuv.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb0 = its.image.compute_image_means(tile) - - img = its.image.convert_capture_to_rgb_image(cap_jpeg, True) - its.image.write_image(img, "%s_jpeg.jpg" % (NAME)) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb1 = its.image.compute_image_means(tile) - - rms_diff = math.sqrt( - sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0) - print "RMS difference:", rms_diff - assert(rms_diff < THRESHOLD_MAX_RMS_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py deleted file mode 100644 index 7a345c9..0000000 --- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import math - -def main(): - """Test capturing a single frame as both RAW and YUV outputs. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_RMS_DIFF = 0.02 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - if (not its.caps.compute_target_exposure(props) or - not its.caps.raw16(props)): - print "Test skipped" - return - - # Use a manual request with a linear tonemap so that the YUV and RAW - # should look the same (once converted by the its.image module). - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req = its.objects.manual_capture_request(s, e, True) - - cap_raw, cap_yuv = cam.do_capture(req, cam.CAP_RAW_YUV) - - img = its.image.convert_capture_to_rgb_image(cap_yuv) - its.image.write_image(img, "%s_yuv.jpg" % (NAME), True) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb0 = its.image.compute_image_means(tile) - - # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the - # tile appropriately. - img = its.image.convert_capture_to_rgb_image(cap_raw, props=props) - its.image.write_image(img, "%s_raw.jpg" % (NAME), True) - tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05) - rgb1 = its.image.compute_image_means(tile) - - rms_diff = math.sqrt( - sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0) - print "RMS difference:", rms_diff - assert(rms_diff < THRESHOLD_MAX_RMS_DIFF) - -if __name__ == '__main__': - main() - diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py deleted file mode 100644 index 15612c5..0000000 --- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2014 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 its.image -import its.caps -import its.device -import its.objects -import its.target -import os.path -import math - -def main(): - """Test capturing a single frame as both RAW10 and YUV outputs. - """ - NAME = os.path.basename(__file__).split(".")[0] - - THRESHOLD_MAX_RMS_DIFF = 0.02 - - with its.device.ItsSession() as cam: - props = cam.get_camera_properties() - - if (not its.caps.compute_target_exposure(props) or - not its.caps.raw10(props)): - print "Test skipped" - return - - # Use a manual request with a linear tonemap so that the YUV and RAW - # should look the same (once converted by the its.image module). - e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"] - req = its.objects.manual_capture_request(s, e, True) - - cap_raw, cap_yuv = cam.do_capture(req, - [{"format":"raw10"}, {"format":"yuv"}]) - - img = its.image.convert_capture_to_rgb_image(cap_yuv) - its.image.write_image(img, "%s_yuv.jpg" % (NAME), True) - tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) - rgb0 = its.image.compute_image_means(tile) - - # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the - # tile appropriately. - img = its.image.convert_capture_to_rgb_image(cap_raw, props=props) - its.image.write_image(img, "%s_raw.jpg" % (NAME), True) - tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05) - rgb1 = its.image.compute_image_means(tile) - - rms_diff = math.sqrt( - sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0) - print "RMS difference:", rms_diff - assert(rms_diff < THRESHOLD_MAX_RMS_DIFF) - -if __name__ == '__main__': - main() - |