1# Copyright 2013 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import its.image 16import its.caps 17import its.device 18import its.objects 19import its.target 20import matplotlib 21import matplotlib.pyplot 22import numpy 23import os.path 24import pylab 25 26def main(): 27 """Test that the android.noiseReduction.mode param is applied when set. 28 29 Capture images with the camera dimly lit. Uses a high analog gain to 30 ensure the captured image is noisy. 31 32 Captures three images, for NR off, "fast", and "high quality". 33 Also captures an image with low gain and NR off, and uses the variance 34 of this as the baseline. 35 """ 36 NAME = os.path.basename(__file__).split(".")[0] 37 38 RELATIVE_ERROR_TOLERANCE = 0.1 39 40 # List of variances for Y,U,V. 41 variances = [[],[],[]] 42 43 # Reference (baseline) variance for each of Y,U,V. 44 ref_variance = [] 45 46 nr_modes_reported = [] 47 48 with its.device.ItsSession() as cam: 49 props = cam.get_camera_properties() 50 its.caps.skip_unless(its.caps.compute_target_exposure(props) and 51 its.caps.per_frame_control(props) and 52 its.caps.noise_reduction_mode(props, 0)) 53 54 # NR mode 0 with low gain 55 e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"] 56 req = its.objects.manual_capture_request(s, e) 57 req["android.noiseReduction.mode"] = 0 58 cap = cam.do_capture(req) 59 its.image.write_image( 60 its.image.convert_capture_to_rgb_image(cap), 61 "%s_low_gain.jpg" % (NAME)) 62 planes = its.image.convert_capture_to_planes(cap) 63 for j in range(3): 64 img = planes[j] 65 tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) 66 ref_variance.append(its.image.compute_image_variances(tile)[0]) 67 print "Ref variances:", ref_variance 68 69 # NR modes 0, 1, 2, 3, 4 with high gain 70 for mode in range(5): 71 # Skip unavailable modes 72 if not its.caps.noise_reduction_mode(props, mode): 73 nr_modes_reported.append(mode) 74 for channel in range(3): 75 variances[channel].append(0) 76 continue; 77 78 e, s = its.target.get_target_exposure_combos(cam)["maxSensitivity"] 79 req = its.objects.manual_capture_request(s, e) 80 req["android.noiseReduction.mode"] = mode 81 cap = cam.do_capture(req) 82 nr_modes_reported.append( 83 cap["metadata"]["android.noiseReduction.mode"]) 84 its.image.write_image( 85 its.image.convert_capture_to_rgb_image(cap), 86 "%s_high_gain_nr=%d.jpg" % (NAME, mode)) 87 planes = its.image.convert_capture_to_planes(cap) 88 for j in range(3): 89 img = planes[j] 90 tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1) 91 variance = its.image.compute_image_variances(tile)[0] 92 variances[j].append(variance / ref_variance[j]) 93 print "Variances with NR mode [0,1,2,3,4]:", variances 94 95 # Draw a plot. 96 for j in range(3): 97 pylab.plot(range(5), variances[j], "rgb"[j]) 98 matplotlib.pyplot.savefig("%s_plot_variances.png" % (NAME)) 99 100 assert(nr_modes_reported == [0,1,2,3,4]) 101 102 for j in range(3): 103 # Smaller variance is better 104 # Verify OFF(0) is not better than FAST(1) 105 assert(variances[j][0] > 106 variances[j][1] * (1.0 - RELATIVE_ERROR_TOLERANCE)) 107 # Verify FAST(1) is not better than HQ(2) 108 assert(variances[j][1] > 109 variances[j][2] * (1.0 - RELATIVE_ERROR_TOLERANCE)) 110 # Verify HQ(2) is better than OFF(0) 111 assert(variances[j][0] > variances[j][2]) 112 if its.caps.noise_reduction_mode(props, 3): 113 # Verify OFF(0) is not better than MINIMAL(3) 114 assert(variances[j][0] > 115 variances[j][3] * (1.0 - RELATIVE_ERROR_TOLERANCE)) 116 # Verify MINIMAL(3) is not better than HQ(2) 117 assert(variances[j][3] > 118 variances[j][2] * (1.0 - RELATIVE_ERROR_TOLERANCE)) 119 if its.caps.noise_reduction_mode(props, 4): 120 # Verify ZSL(4) is close to MINIMAL(3) 121 assert(numpy.isclose(variances[j][4], variances[j][3], 122 RELATIVE_ERROR_TOLERANCE)) 123 elif its.caps.noise_reduction_mode(props, 4): 124 # Verify ZSL(4) is close to OFF(0) 125 assert(numpy.isclose(variances[j][4], variances[j][0], 126 RELATIVE_ERROR_TOLERANCE)) 127 128if __name__ == '__main__': 129 main() 130 131