xref: /aosp_15_r20/system/media/camera/docs/plots.py (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
1*b9df5ad1SAndroid Build Coastguard Worker#!/bin/ipython
2*b9df5ad1SAndroid Build Coastguard Worker
3*b9df5ad1SAndroid Build Coastguard Workerimport argparse
4*b9df5ad1SAndroid Build Coastguard Workerimport numpy as np
5*b9df5ad1SAndroid Build Coastguard Workerimport matplotlib.pyplot as plt
6*b9df5ad1SAndroid Build Coastguard Workerimport sys
7*b9df5ad1SAndroid Build Coastguard Worker
8*b9df5ad1SAndroid Build Coastguard Worker## general defines
9*b9df5ad1SAndroid Build Coastguard Worker
10*b9df5ad1SAndroid Build Coastguard Workerlinecolor = "#%x%x%x" % ( 217, 234, 211 )
11*b9df5ad1SAndroid Build Coastguard Workermarkercolor = "#%x%x%x" % ( 217/2, 234/2, 211/2 )
12*b9df5ad1SAndroid Build Coastguard Worker
13*b9df5ad1SAndroid Build Coastguard Worker# Draw pretty plot
14*b9df5ad1SAndroid Build Coastguard Workerdef doc_plot(fig, x, y):
15*b9df5ad1SAndroid Build Coastguard Worker
16*b9df5ad1SAndroid Build Coastguard Worker  plt.figure(fig.number)
17*b9df5ad1SAndroid Build Coastguard Worker  fig.clear()
18*b9df5ad1SAndroid Build Coastguard Worker
19*b9df5ad1SAndroid Build Coastguard Worker  lines, = plt.plot(x,y)
20*b9df5ad1SAndroid Build Coastguard Worker  lines.set_color(linecolor)
21*b9df5ad1SAndroid Build Coastguard Worker  lines.set_linewidth(4)
22*b9df5ad1SAndroid Build Coastguard Worker  lines.set_marker('o')
23*b9df5ad1SAndroid Build Coastguard Worker  lines.set_markeredgecolor(markercolor)
24*b9df5ad1SAndroid Build Coastguard Worker  lines.set_markersize(6)
25*b9df5ad1SAndroid Build Coastguard Worker  lines.set_markeredgewidth(2)
26*b9df5ad1SAndroid Build Coastguard Worker
27*b9df5ad1SAndroid Build Coastguard Worker  axes = fig.get_axes()[0]
28*b9df5ad1SAndroid Build Coastguard Worker  axes.set_aspect(1)
29*b9df5ad1SAndroid Build Coastguard Worker  axes.set_ybound(0,1)
30*b9df5ad1SAndroid Build Coastguard Worker  axes.set_xbound(0,1)
31*b9df5ad1SAndroid Build Coastguard Worker  axes.grid(True)
32*b9df5ad1SAndroid Build Coastguard Worker  axes.xaxis.label.set_text(r'$P_{IN}$')
33*b9df5ad1SAndroid Build Coastguard Worker  axes.xaxis.label.set_fontsize(14)
34*b9df5ad1SAndroid Build Coastguard Worker  axes.yaxis.label.set_text(r'$P_{OUT}$')
35*b9df5ad1SAndroid Build Coastguard Worker  axes.yaxis.label.set_fontsize(14)
36*b9df5ad1SAndroid Build Coastguard Worker
37*b9df5ad1SAndroid Build Coastguard Worker# Print out interleaved coefficients for HAL3 tonemap curve tags
38*b9df5ad1SAndroid Build Coastguard Workerdef doc_coeff(x,y):
39*b9df5ad1SAndroid Build Coastguard Worker  coeffs = np.vstack((x, y)).reshape(-1,order='F')
40*b9df5ad1SAndroid Build Coastguard Worker  coeff_str = "[ "
41*b9df5ad1SAndroid Build Coastguard Worker  for val in coeffs[:-1]:
42*b9df5ad1SAndroid Build Coastguard Worker    coeff_str += "%0.4f, " % val
43*b9df5ad1SAndroid Build Coastguard Worker
44*b9df5ad1SAndroid Build Coastguard Worker  coeff_str += "%0.4f ]" % coeffs[-1]
45*b9df5ad1SAndroid Build Coastguard Worker
46*b9df5ad1SAndroid Build Coastguard Worker  print(coeff_str)
47*b9df5ad1SAndroid Build Coastguard Worker
48*b9df5ad1SAndroid Build Coastguard Workerdef doc_map(fig, imgMap, index):
49*b9df5ad1SAndroid Build Coastguard Worker  plt.figure(fig.number)
50*b9df5ad1SAndroid Build Coastguard Worker  fig.clear()
51*b9df5ad1SAndroid Build Coastguard Worker  plt.imshow(imgMap - 1, interpolation='nearest')
52*b9df5ad1SAndroid Build Coastguard Worker  for x in range(0, np.size(imgMap, 1)):
53*b9df5ad1SAndroid Build Coastguard Worker    for y in range(0, np.size(imgMap, 0)):
54*b9df5ad1SAndroid Build Coastguard Worker      plt.text(x,y, imgMap[y,x,index], color='white')
55*b9df5ad1SAndroid Build Coastguard Worker
56*b9df5ad1SAndroid Build Coastguard Worker  axes = fig.get_axes()[0]
57*b9df5ad1SAndroid Build Coastguard Worker  axes.set_xticks(range(0, np.size(imgMap, 1)))
58*b9df5ad1SAndroid Build Coastguard Worker  axes.set_yticks(range(0, np.size(imgMap, 0)))
59*b9df5ad1SAndroid Build Coastguard Worker
60*b9df5ad1SAndroid Build Coastguard Worker## Check arguments
61*b9df5ad1SAndroid Build Coastguard Worker
62*b9df5ad1SAndroid Build Coastguard Workerparser = argparse.ArgumentParser(description='Draw plots for camera HAL3.x implementation spec doc')
63*b9df5ad1SAndroid Build Coastguard Workerparser.add_argument('--save_figures', default=False, action='store_true',
64*b9df5ad1SAndroid Build Coastguard Worker                   help='Save figures as pngs')
65*b9df5ad1SAndroid Build Coastguard Worker
66*b9df5ad1SAndroid Build Coastguard Workerargs = parser.parse_args()
67*b9df5ad1SAndroid Build Coastguard Worker
68*b9df5ad1SAndroid Build Coastguard Worker## Linear mapping
69*b9df5ad1SAndroid Build Coastguard Worker
70*b9df5ad1SAndroid Build Coastguard Workerx_lin = np.linspace(0,1,2)
71*b9df5ad1SAndroid Build Coastguard Workery_lin = x_lin
72*b9df5ad1SAndroid Build Coastguard Worker
73*b9df5ad1SAndroid Build Coastguard Workerlin_fig = plt.figure(1)
74*b9df5ad1SAndroid Build Coastguard Workerdoc_plot(lin_fig, x_lin, y_lin)
75*b9df5ad1SAndroid Build Coastguard Worker
76*b9df5ad1SAndroid Build Coastguard Workerlin_title = 'Linear tonemapping curve'
77*b9df5ad1SAndroid Build Coastguard Workerplt.title(lin_title)
78*b9df5ad1SAndroid Build Coastguard Workerprint(lin_title)
79*b9df5ad1SAndroid Build Coastguard Workerdoc_coeff(x_lin, y_lin)
80*b9df5ad1SAndroid Build Coastguard Worker
81*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
82*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('linear_tonemap.png',bbox_inches='tight')
83*b9df5ad1SAndroid Build Coastguard Worker
84*b9df5ad1SAndroid Build Coastguard Worker## Inverse mapping
85*b9df5ad1SAndroid Build Coastguard Worker
86*b9df5ad1SAndroid Build Coastguard Workerx_inv = x_lin
87*b9df5ad1SAndroid Build Coastguard Workery_inv = 1 - x_lin
88*b9df5ad1SAndroid Build Coastguard Worker
89*b9df5ad1SAndroid Build Coastguard Workerinv_fig = plt.figure(2)
90*b9df5ad1SAndroid Build Coastguard Workerdoc_plot(inv_fig, x_inv, y_inv)
91*b9df5ad1SAndroid Build Coastguard Worker
92*b9df5ad1SAndroid Build Coastguard Workerinv_title = 'Inverting tonemapping curve'
93*b9df5ad1SAndroid Build Coastguard Workerplt.title(inv_title)
94*b9df5ad1SAndroid Build Coastguard Workerprint(inv_title)
95*b9df5ad1SAndroid Build Coastguard Workerdoc_coeff(x_inv, y_inv)
96*b9df5ad1SAndroid Build Coastguard Worker
97*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
98*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('inverse_tonemap.png',bbox_inches='tight')
99*b9df5ad1SAndroid Build Coastguard Worker
100*b9df5ad1SAndroid Build Coastguard Worker## Gamma 1/2.2
101*b9df5ad1SAndroid Build Coastguard Worker
102*b9df5ad1SAndroid Build Coastguard Workerx_gamma = np.linspace(0, 1, 16);
103*b9df5ad1SAndroid Build Coastguard Worker
104*b9df5ad1SAndroid Build Coastguard Workery_gamma = x_gamma**(1/2.2)
105*b9df5ad1SAndroid Build Coastguard Worker
106*b9df5ad1SAndroid Build Coastguard Workergamma_fig = plt.figure(3)
107*b9df5ad1SAndroid Build Coastguard Workerdoc_plot(gamma_fig, x_gamma, y_gamma)
108*b9df5ad1SAndroid Build Coastguard Worker
109*b9df5ad1SAndroid Build Coastguard Workergamma_title = r'$\gamma=1/2.2$ tonemapping curve'
110*b9df5ad1SAndroid Build Coastguard Workerplt.title(gamma_title)
111*b9df5ad1SAndroid Build Coastguard Workerprint(gamma_title)
112*b9df5ad1SAndroid Build Coastguard Workerdoc_coeff(x_gamma, y_gamma)
113*b9df5ad1SAndroid Build Coastguard Worker
114*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
115*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('gamma_tonemap.png',bbox_inches='tight')
116*b9df5ad1SAndroid Build Coastguard Worker
117*b9df5ad1SAndroid Build Coastguard Worker## sRGB curve
118*b9df5ad1SAndroid Build Coastguard Worker
119*b9df5ad1SAndroid Build Coastguard Workerx_srgb = x_gamma
120*b9df5ad1SAndroid Build Coastguard Workery_srgb = np.where(x_srgb <= 0.0031308, x_srgb * 12.92, 1.055*x_srgb**(1/2.4)-0.055)
121*b9df5ad1SAndroid Build Coastguard Worker
122*b9df5ad1SAndroid Build Coastguard Workersrgb_fig = plt.figure(4)
123*b9df5ad1SAndroid Build Coastguard Workerdoc_plot(srgb_fig, x_srgb, y_srgb)
124*b9df5ad1SAndroid Build Coastguard Worker
125*b9df5ad1SAndroid Build Coastguard Workersrgb_title = 'sRGB tonemapping curve'
126*b9df5ad1SAndroid Build Coastguard Workerplt.title(srgb_title)
127*b9df5ad1SAndroid Build Coastguard Workerprint(srgb_title)
128*b9df5ad1SAndroid Build Coastguard Workerdoc_coeff(x_srgb, y_srgb)
129*b9df5ad1SAndroid Build Coastguard Worker
130*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
131*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('srgb_tonemap.png',bbox_inches='tight')
132*b9df5ad1SAndroid Build Coastguard Worker
133*b9df5ad1SAndroid Build Coastguard Worker## Sample lens shading map
134*b9df5ad1SAndroid Build Coastguard Worker
135*b9df5ad1SAndroid Build Coastguard WorkershadingMapSize = np.array([3, 4])
136*b9df5ad1SAndroid Build Coastguard WorkershadingMap1 = np.array(
137*b9df5ad1SAndroid Build Coastguard Worker    [ 1.3, 1.2, 1.15, 1.2,  1.2, 1.2, 1.15, 1.2,  1.1, 1.2, 1.2, 1.2,  1.3, 1.2, 1.3, 1.3,
138*b9df5ad1SAndroid Build Coastguard Worker      1.2, 1.2, 1.25, 1.1,  1.1, 1.1, 1.1, 1.0,   1.0, 1.0, 1.0, 1.0,  1.2, 1.3, 1.25, 1.2,
139*b9df5ad1SAndroid Build Coastguard Worker      1.3, 1.2, 1.2, 1.3,   1.2, 1.15, 1.1, 1.2,  1.2, 1.1, 1.0, 1.2,  1.3, 1.15, 1.2, 1.3 ])
140*b9df5ad1SAndroid Build Coastguard WorkerredMap = shadingMap1[0::4].reshape(shadingMapSize)
141*b9df5ad1SAndroid Build Coastguard WorkergreenEMap = shadingMap1[1::4].reshape(shadingMapSize)
142*b9df5ad1SAndroid Build Coastguard WorkergreenOMap = shadingMap1[2::4].reshape(shadingMapSize)
143*b9df5ad1SAndroid Build Coastguard WorkerblueMap = shadingMap1[3::4].reshape(shadingMapSize)
144*b9df5ad1SAndroid Build Coastguard Worker
145*b9df5ad1SAndroid Build Coastguard WorkerrgbMap = np.dstack( (redMap, (greenEMap + greenOMap) / 2, blueMap) )
146*b9df5ad1SAndroid Build Coastguard WorkerredMap = np.dstack( (redMap, np.zeros(shadingMapSize), np.zeros(shadingMapSize) ) )
147*b9df5ad1SAndroid Build Coastguard WorkergreenEMap = np.dstack( (np.zeros(shadingMapSize), greenEMap, np.zeros(shadingMapSize) ) )
148*b9df5ad1SAndroid Build Coastguard WorkergreenOMap = np.dstack( (np.zeros(shadingMapSize), greenOMap, np.zeros(shadingMapSize) ) )
149*b9df5ad1SAndroid Build Coastguard WorkerblueMap = np.dstack( (np.zeros(shadingMapSize), np.zeros(shadingMapSize), blueMap ) )
150*b9df5ad1SAndroid Build Coastguard Worker
151*b9df5ad1SAndroid Build Coastguard WorkerredImg = plt.figure(5)
152*b9df5ad1SAndroid Build Coastguard Workerdoc_map(redImg, redMap, 0)
153*b9df5ad1SAndroid Build Coastguard Workerplt.title('Red lens shading map')
154*b9df5ad1SAndroid Build Coastguard Worker
155*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
156*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('red_shading.png',bbox_inches='tight')
157*b9df5ad1SAndroid Build Coastguard Worker
158*b9df5ad1SAndroid Build Coastguard WorkergreenEImg = plt.figure(6)
159*b9df5ad1SAndroid Build Coastguard Workerdoc_map(greenEImg, greenEMap, 1)
160*b9df5ad1SAndroid Build Coastguard Workerplt.title('Green (even rows) lens shading map')
161*b9df5ad1SAndroid Build Coastguard Worker
162*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
163*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('green_e_shading.png',bbox_inches='tight')
164*b9df5ad1SAndroid Build Coastguard Worker
165*b9df5ad1SAndroid Build Coastguard WorkergreenOImg = plt.figure(7)
166*b9df5ad1SAndroid Build Coastguard Workerdoc_map(greenOImg, greenOMap, 1)
167*b9df5ad1SAndroid Build Coastguard Workerplt.title('Green (odd rows) lens shading map')
168*b9df5ad1SAndroid Build Coastguard Worker
169*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
170*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('green_o_shading.png',bbox_inches='tight')
171*b9df5ad1SAndroid Build Coastguard Worker
172*b9df5ad1SAndroid Build Coastguard WorkerblueImg = plt.figure(8)
173*b9df5ad1SAndroid Build Coastguard Workerdoc_map(blueImg, blueMap, 2)
174*b9df5ad1SAndroid Build Coastguard Workerplt.title('Blue lens shading map')
175*b9df5ad1SAndroid Build Coastguard Worker
176*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
177*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('blue_shading.png',bbox_inches='tight')
178*b9df5ad1SAndroid Build Coastguard Worker
179*b9df5ad1SAndroid Build Coastguard WorkerrgbImg = plt.figure(9)
180*b9df5ad1SAndroid Build Coastguard Worker
181*b9df5ad1SAndroid Build Coastguard WorkerrgbImg.clear()
182*b9df5ad1SAndroid Build Coastguard Workerplt.imshow(1/rgbMap,interpolation='bicubic')
183*b9df5ad1SAndroid Build Coastguard Worker
184*b9df5ad1SAndroid Build Coastguard Workeraxes = rgbImg.get_axes()[0]
185*b9df5ad1SAndroid Build Coastguard Workeraxes.set_xticks(range(0, np.size(rgbMap, 1)))
186*b9df5ad1SAndroid Build Coastguard Workeraxes.set_yticks(range(0, np.size(rgbMap, 0)))
187*b9df5ad1SAndroid Build Coastguard Worker
188*b9df5ad1SAndroid Build Coastguard Workerplt.title('Image of uniform white wall (inverse shading map)')
189*b9df5ad1SAndroid Build Coastguard Worker
190*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
191*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('inv_shading.png',bbox_inches='tight')
192*b9df5ad1SAndroid Build Coastguard Worker
193*b9df5ad1SAndroid Build Coastguard Worker# Rec. 709
194*b9df5ad1SAndroid Build Coastguard Workerx_rec709 = x_gamma
195*b9df5ad1SAndroid Build Coastguard Workery_rec709 = np.where(x_rec709 <= 0.018, x_rec709 * 4.500, 1.099*x_rec709**0.45-0.099)
196*b9df5ad1SAndroid Build Coastguard Worker
197*b9df5ad1SAndroid Build Coastguard Workerrec709_fig = plt.figure(10)
198*b9df5ad1SAndroid Build Coastguard Workerdoc_plot(rec709_fig, x_rec709, y_rec709)
199*b9df5ad1SAndroid Build Coastguard Worker
200*b9df5ad1SAndroid Build Coastguard Workerrec709_title = 'Rec. 709 tonemapping curve'
201*b9df5ad1SAndroid Build Coastguard Workerplt.title(rec709_title)
202*b9df5ad1SAndroid Build Coastguard Workerprint(rec709_title)
203*b9df5ad1SAndroid Build Coastguard Workerdoc_coeff(x_rec709, y_rec709)
204*b9df5ad1SAndroid Build Coastguard Worker
205*b9df5ad1SAndroid Build Coastguard Workerif args.save_figures:
206*b9df5ad1SAndroid Build Coastguard Worker  plt.savefig('rec709_tonemap.png',bbox_inches='tight')
207*b9df5ad1SAndroid Build Coastguard Worker
208*b9df5ad1SAndroid Build Coastguard Worker
209*b9df5ad1SAndroid Build Coastguard Worker# Show figures
210*b9df5ad1SAndroid Build Coastguard Worker
211*b9df5ad1SAndroid Build Coastguard Workerplt.show()
212