utils: raspberrypi: ctt: Add a maximum gain parameter for LSC

A max_gain parameter is added to the config file which we pass to the
lens shading calibration. This clamps the maximum luminance gain that
gets written into the tuning files so as to prevent overflows.

It is particularly useful for lenses that cut off the light completely
from the sensor corners, and allows usable tables to be generated for
them.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
David Plowman 2024-06-06 11:15:12 +01:00 committed by Kieran Bingham
parent b40d9dbc0b
commit 6960684fa1
3 changed files with 16 additions and 9 deletions

View file

@ -269,7 +269,7 @@ class Camera:
colour channel seperately, and then partially corrects for vignetting. colour channel seperately, and then partially corrects for vignetting.
The extent of the correction depends on the 'luminance_strength' parameter. The extent of the correction depends on the 'luminance_strength' parameter.
""" """
def alsc_cal(self, luminance_strength, do_alsc_colour, grid_size): def alsc_cal(self, luminance_strength, do_alsc_colour, grid_size, max_gain=8.0):
if 'rpi.alsc' in self.disable: if 'rpi.alsc' in self.disable:
return 1 return 1
print('\nStarting ALSC calibration') print('\nStarting ALSC calibration')
@ -292,7 +292,7 @@ class Camera:
call calibration function call calibration function
""" """
plot = "rpi.alsc" in self.plot plot = "rpi.alsc" in self.plot
alsc_out = alsc_all(self, do_alsc_colour, plot, grid_size) alsc_out = alsc_all(self, do_alsc_colour, plot, grid_size, max_gain=max_gain)
cal_cr_list, cal_cb_list, luminance_lut, av_corn = alsc_out cal_cr_list, cal_cb_list, luminance_lut, av_corn = alsc_out
""" """
write output to json and finish if not do_alsc_colour write output to json and finish if not do_alsc_colour
@ -705,11 +705,13 @@ def run_ctt(json_output, directory, config, log_output, json_template, grid_size
alsc_d = get_config(configs, "alsc", {}, 'dict') alsc_d = get_config(configs, "alsc", {}, 'dict')
do_alsc_colour = get_config(alsc_d, "do_alsc_colour", 1, 'bool') do_alsc_colour = get_config(alsc_d, "do_alsc_colour", 1, 'bool')
luminance_strength = get_config(alsc_d, "luminance_strength", 0.8, 'num') luminance_strength = get_config(alsc_d, "luminance_strength", 0.8, 'num')
lsc_max_gain = get_config(alsc_d, "max_gain", 8.0, 'num')
blacklevel = get_config(configs, "blacklevel", -1, 'num') blacklevel = get_config(configs, "blacklevel", -1, 'num')
macbeth_d = get_config(configs, "macbeth", {}, 'dict') macbeth_d = get_config(configs, "macbeth", {}, 'dict')
mac_small = get_config(macbeth_d, "small", 0, 'bool') mac_small = get_config(macbeth_d, "small", 0, 'bool')
mac_show = get_config(macbeth_d, "show", 0, 'bool') mac_show = get_config(macbeth_d, "show", 0, 'bool')
mac_config = (mac_small, mac_show) mac_config = (mac_small, mac_show)
print("Read lsc_max_gain", lsc_max_gain)
if blacklevel < -1 or blacklevel >= 2**16: if blacklevel < -1 or blacklevel >= 2**16:
print('\nInvalid blacklevel, defaulted to 64') print('\nInvalid blacklevel, defaulted to 64')
@ -750,7 +752,7 @@ def run_ctt(json_output, directory, config, log_output, json_template, grid_size
Cam.json['rpi.black_level']['black_level'] = Cam.blacklevel_16 Cam.json['rpi.black_level']['black_level'] = Cam.blacklevel_16
Cam.json_remove(disable) Cam.json_remove(disable)
print('\nSTARTING CALIBRATIONS') print('\nSTARTING CALIBRATIONS')
Cam.alsc_cal(luminance_strength, do_alsc_colour, grid_size) Cam.alsc_cal(luminance_strength, do_alsc_colour, grid_size, max_gain=lsc_max_gain)
Cam.geq_cal() Cam.geq_cal()
Cam.lux_cal() Cam.lux_cal()
Cam.noise_cal() Cam.noise_cal()

View file

@ -13,7 +13,7 @@ from mpl_toolkits.mplot3d import Axes3D
""" """
preform alsc calibration on a set of images preform alsc calibration on a set of images
""" """
def alsc_all(Cam, do_alsc_colour, plot, grid_size=(16, 12)): def alsc_all(Cam, do_alsc_colour, plot, grid_size=(16, 12), max_gain=8.0):
imgs_alsc = Cam.imgs_alsc imgs_alsc = Cam.imgs_alsc
grid_w, grid_h = grid_size grid_w, grid_h = grid_size
""" """
@ -24,7 +24,7 @@ def alsc_all(Cam, do_alsc_colour, plot, grid_size=(16, 12)):
list_cb = [] list_cb = []
list_cg = [] list_cg = []
for Img in imgs_alsc: for Img in imgs_alsc:
col, cr, cb, cg, size = alsc(Cam, Img, do_alsc_colour, plot, grid_size=grid_size) col, cr, cb, cg, size = alsc(Cam, Img, do_alsc_colour, plot, grid_size=grid_size, max_gain=max_gain)
list_col.append(col) list_col.append(col)
list_cr.append(cr) list_cr.append(cr)
list_cb.append(cb) list_cb.append(cb)
@ -118,7 +118,7 @@ def alsc_all(Cam, do_alsc_colour, plot, grid_size=(16, 12)):
""" """
calculate g/r and g/b for 32x32 points arranged in a grid for a single image calculate g/r and g/b for 32x32 points arranged in a grid for a single image
""" """
def alsc(Cam, Img, do_alsc_colour, plot=False, grid_size=(16, 12)): def alsc(Cam, Img, do_alsc_colour, plot=False, grid_size=(16, 12), max_gain=8.0):
Cam.log += '\nProcessing image: ' + Img.name Cam.log += '\nProcessing image: ' + Img.name
grid_w, grid_h = grid_size grid_w, grid_h = grid_size
""" """
@ -153,9 +153,12 @@ def alsc(Cam, Img, do_alsc_colour, plot=False, grid_size=(16, 12)):
median blur to remove peaks and save as float 64 median blur to remove peaks and save as float 64
""" """
cr = cv2.medianBlur(cr, 3).astype('float64') cr = cv2.medianBlur(cr, 3).astype('float64')
cr = cr/np.min(cr) # gain tables are easier for humans to read if the minimum is 1.0
cb = cv2.medianBlur(cb, 3).astype('float64') cb = cv2.medianBlur(cb, 3).astype('float64')
cb = cb/np.min(cb)
cg = cv2.medianBlur(cg, 3).astype('float64') cg = cv2.medianBlur(cg, 3).astype('float64')
cg = cg/np.min(cg) cg = cg/np.min(cg)
cg = [min(v, max_gain) for v in cg.flatten()] # never exceed the max luminance gain
""" """
debugging code showing 2D surface plot of vignetting. Quite useful for debugging code showing 2D surface plot of vignetting. Quite useful for
@ -179,7 +182,7 @@ def alsc(Cam, Img, do_alsc_colour, plot=False, grid_size=(16, 12)):
# print(Img.str) # print(Img.str)
plt.show() plt.show()
return Img.col, cr.flatten(), cb.flatten(), cg.flatten(), (w, h, dx, dy) return Img.col, cr.flatten(), cb.flatten(), cg, (w, h, dx, dy)
else: else:
""" """
@ -189,6 +192,7 @@ def alsc(Cam, Img, do_alsc_colour, plot=False, grid_size=(16, 12)):
cg = np.reshape(1/g, (grid_h, grid_w)).astype('float32') cg = np.reshape(1/g, (grid_h, grid_w)).astype('float32')
cg = cv2.medianBlur(cg, 3).astype('float64') cg = cv2.medianBlur(cg, 3).astype('float64')
cg = cg/np.min(cg) cg = cg/np.min(cg)
cg = [min(v, max_gain) for v in cg.flatten()] # never exceed the max luminance gain
if plot: if plot:
hf = plt.figure(figssize=(8, 8)) hf = plt.figure(figssize=(8, 8))

View file

@ -3,7 +3,8 @@
"plot": [], "plot": [],
"alsc": { "alsc": {
"do_alsc_colour": 1, "do_alsc_colour": 1,
"luminance_strength": 0.5 "luminance_strength": 0.8,
"max_gain": 8.0
}, },
"awb": { "awb": {
"greyworld": 0 "greyworld": 0
@ -13,4 +14,4 @@
"small": 0, "small": 0,
"show": 0 "show": 0
} }
} }