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.image 16 import its.device 17 import its.dng 18 import its.objects 19 import numpy 20 import os.path 21 22 def main(): 23 """Test that the DNG tags are internally self-consistent. 24 """ 25 NAME = os.path.basename(__file__).split(".")[0] 26 27 with its.device.ItsSession() as cam: 28 props = cam.get_camera_properties() 29 30 # Assumes that illuminant 1 is D65, and illuminant 2 is standard A. 31 # TODO: Generalize DNG tags check for any provided illuminants. 32 illum_code = [21, 17] # D65, A 33 illum_str = ['D65', 'A'] 34 ref_str = ['android.sensor.referenceIlluminant%d'%(i) for i in [1,2]] 35 cm_str = ['android.sensor.colorTransform%d'%(i) for i in [1,2]] 36 fm_str = ['android.sensor.forwardMatrix%d'%(i) for i in [1,2]] 37 cal_str = ['android.sensor.calibrationTransform%d'%(i) for i in [1,2]] 38 dng_illum = [its.dng.D65, its.dng.A] 39 40 for i in [0,1]: 41 assert(props[ref_str[i]] == illum_code[i]) 42 raw_input("\n[Point camera at grey card under %s and press ENTER]"%( 43 illum_str[i])) 44 45 cam.do_3a(do_af=False) 46 cap = cam.do_capture(its.objects.auto_capture_request()) 47 gains = cap["metadata"]["android.colorCorrection.gains"] 48 ccm = its.objects.rational_to_float( 49 cap["metadata"]["android.colorCorrection.transform"]) 50 cal = its.objects.rational_to_float(props[cal_str[i]]) 51 print "HAL reported gains:\n", numpy.array(gains) 52 print "HAL reported ccm:\n", numpy.array(ccm).reshape(3,3) 53 print "HAL reported cal:\n", numpy.array(cal).reshape(3,3) 54 55 # Dump the image. 56 img = its.image.convert_capture_to_rgb_image(cap) 57 its.image.write_image(img, "%s_%s.jpg" % (NAME, illum_str[i])) 58 59 # Compute the matrices that are expected under this illuminant from 60 # the HAL-reported WB gains, CCM, and calibration matrix. 61 cm, fm = its.dng.compute_cm_fm(dng_illum[i], gains, ccm, cal) 62 asn = its.dng.compute_asn(dng_illum[i], cal, cm) 63 print "Expected ColorMatrix:\n", cm 64 print "Expected ForwardMatrix:\n", fm 65 print "Expected AsShotNeutral:\n", asn 66 67 # Get the matrices that are reported by the HAL for this 68 # illuminant. 69 cm_ref = numpy.array(its.objects.rational_to_float( 70 props[cm_str[i]])).reshape(3,3) 71 fm_ref = numpy.array(its.objects.rational_to_float( 72 props[fm_str[i]])).reshape(3,3) 73 asn_ref = numpy.array(its.objects.rational_to_float( 74 cap['metadata']['android.sensor.neutralColorPoint'])) 75 print "Reported ColorMatrix:\n", cm_ref 76 print "Reported ForwardMatrix:\n", fm_ref 77 print "Reported AsShotNeutral:\n", asn_ref 78 79 # The color matrix may be scaled (between the reported and 80 # expected values). 81 cm_scale = cm.mean(1).mean(0) / cm_ref.mean(1).mean(0) 82 print "ColorMatrix scale factor:", cm_scale 83 84 # Compute the deltas between reported and expected. 85 print "Ratios in ColorMatrix:\n", cm / cm_ref 86 print "Deltas in ColorMatrix (after normalizing):\n", cm/cm_scale - cm_ref 87 print "Deltas in ForwardMatrix:\n", fm - fm_ref 88 print "Deltas in AsShotNeutral:\n", asn - asn_ref 89 90 # TODO: Add pass/fail test on DNG matrices. 91 92 if __name__ == '__main__': 93 main() 94 95