1 # Copyright 2014 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 15 import its.device 16 import its.caps 17 import its.objects 18 import its.image 19 import os.path 20 import pylab 21 import matplotlib 22 import matplotlib.pyplot 23 24 def main(): 25 """Capture a set of raw images with increasing gains and measure the noise. 26 27 Capture raw-only, in a burst. 28 """ 29 NAME = os.path.basename(__file__).split(".")[0] 30 31 # Each shot must be 1% noisier (by the variance metric) than the previous 32 # one. 33 VAR_THRESH = 1.01 34 35 NUM_STEPS = 5 36 37 with its.device.ItsSession() as cam: 38 39 props = cam.get_camera_properties() 40 its.caps.skip_unless(its.caps.raw16(props) and 41 its.caps.manual_sensor(props) and 42 its.caps.read_3a(props) and 43 its.caps.per_frame_control(props)) 44 45 # Expose for the scene with min sensitivity 46 sens_min, sens_max = props['android.sensor.info.sensitivityRange'] 47 # Digital gains might not be visible on RAW data 48 sens_max = props['android.sensor.maxAnalogSensitivity'] 49 sens_step = (sens_max - sens_min) / NUM_STEPS 50 s_ae,e_ae,_,_,f_dist = cam.do_3a(get_results=True) 51 s_e_prod = s_ae * e_ae 52 53 reqs = [] 54 settings = [] 55 for s in range(sens_min, sens_max, sens_step): 56 e = int(s_e_prod / float(s)) 57 req = its.objects.manual_capture_request(s, e, f_dist) 58 reqs.append(req) 59 settings.append((s,e)) 60 61 caps = cam.do_capture(reqs, cam.CAP_RAW) 62 63 variances = [] 64 for i,cap in enumerate(caps): 65 (s,e) = settings[i] 66 67 # Measure the variance. Each shot should be noisier than the 68 # previous shot (as the gain is increasing). 69 plane = its.image.convert_capture_to_planes(cap, props)[1] 70 tile = its.image.get_image_patch(plane, 0.45,0.45,0.1,0.1) 71 var = its.image.compute_image_variances(tile)[0] 72 variances.append(var) 73 74 img = its.image.convert_capture_to_rgb_image(cap, props=props) 75 its.image.write_image(img, "%s_s=%05d_var=%f.jpg" % (NAME,s,var)) 76 print "s=%d, e=%d, var=%e"%(s,e,var) 77 78 pylab.plot(range(len(variances)), variances) 79 matplotlib.pyplot.savefig("%s_variances.png" % (NAME)) 80 81 # Test that each shot is noisier than the previous one. 82 for i in range(len(variances) - 1): 83 assert(variances[i] < variances[i+1] / VAR_THRESH) 84 85 if __name__ == '__main__': 86 main() 87 88