Skip to content

Commit f715a75

Browse files
committed
utils: libtuning: modules: alsc: Add rkisp1 LSC module
Add an LSC module for RkISP1. Signed-off-by: Paul Elder <[email protected]> Reviewed-by: Laurent Pinchart <[email protected]>
1 parent 280e4ac commit f715a75

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

utils/tuning/libtuning/modules/lsc/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
from libtuning.modules.lsc.lsc import LSC
66
from libtuning.modules.lsc.raspberrypi import ALSCRaspberryPi
7+
from libtuning.modules.lsc.rkisp1 import LSCRkISP1
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# SPDX-License-Identifier: BSD-2-Clause
2+
#
3+
# Copyright (C) 2019, Raspberry Pi Ltd
4+
# Copyright (C) 2022, Paul Elder <[email protected]>
5+
#
6+
# rkisp1.py - LSC module for tuning rkisp1
7+
8+
from .lsc import LSC
9+
10+
import libtuning as lt
11+
import libtuning.utils as utils
12+
13+
from numbers import Number
14+
import numpy as np
15+
16+
17+
class LSCRkISP1(LSC):
18+
hr_name = 'LSC (RkISP1)'
19+
out_name = 'LensShadingCorrection'
20+
# \todo Not sure if this is useful. Probably will remove later.
21+
compatible = ['rkisp1']
22+
23+
def __init__(self, *args, **kwargs):
24+
super().__init__(**kwargs)
25+
26+
# We don't actually need anything from the config file
27+
def validate_config(self, config: dict) -> bool:
28+
return True
29+
30+
# @return Image color temperature, flattened array of red calibration table
31+
# (containing {sector size} elements), flattened array of blue
32+
# calibration table, flattened array of (red's) green calibration
33+
# table, flattened array of (blue's) green calibration table
34+
35+
def _do_single_lsc(self, image: lt.Image):
36+
cgr, gr = self._lsc_single_channel(image.channels[lt.Color.GR], image)
37+
cgb, gb = self._lsc_single_channel(image.channels[lt.Color.GB], image)
38+
39+
# \todo Should these ratio against the average of both greens or just
40+
# each green like we've done here?
41+
cr, _ = self._lsc_single_channel(image.channels[lt.Color.R], image, gr)
42+
cb, _ = self._lsc_single_channel(image.channels[lt.Color.B], image, gb)
43+
44+
return image.color, cr.flatten(), cb.flatten(), cgr.flatten(), cgb.flatten()
45+
46+
# @return List of dictionaries of color temperature, red table, red's green
47+
# table, blue's green table, and blue table
48+
49+
def _do_all_lsc(self, images: list) -> list:
50+
output_list = []
51+
output_map_func = lt.gradient.Linear().map
52+
53+
# List of colour temperatures
54+
list_col = []
55+
# Associated calibration tables
56+
list_cr = []
57+
list_cb = []
58+
list_cgr = []
59+
list_cgb = []
60+
for image in self._enumerate_lsc_images(images):
61+
col, cr, cb, cgr, cgb = self._do_single_lsc(image)
62+
list_col.append(col)
63+
list_cr.append(cr)
64+
list_cb.append(cb)
65+
list_cgr.append(cgr)
66+
list_cgb.append(cgb)
67+
68+
# Convert to numpy array for data manipulation
69+
list_col = np.array(list_col)
70+
list_cr = np.array(list_cr)
71+
list_cb = np.array(list_cb)
72+
list_cgr = np.array(list_cgr)
73+
list_cgb = np.array(list_cgb)
74+
75+
for color_temperature in sorted(set(list_col)):
76+
# Average tables for the same colour temperature
77+
indices = np.where(list_col == color_temperature)
78+
color_temperature = int(color_temperature)
79+
80+
tables = []
81+
for lis in [list_cr, list_cgr, list_cgb, list_cb]:
82+
table = np.mean(lis[indices], axis=0)
83+
table = output_map_func((1, 3.999), (1024, 4095), table)
84+
table = np.round(table).astype('int32').tolist()
85+
tables.append(table)
86+
87+
entry = {
88+
'ct': color_temperature,
89+
'r': tables[0],
90+
'gr': tables[1],
91+
'gb': tables[2],
92+
'b': tables[3],
93+
}
94+
95+
output_list.append(entry)
96+
97+
return output_list
98+
99+
def process(self, config: dict, images: list, outputs: dict) -> dict:
100+
output = {}
101+
102+
# \todo This should actually come from self.sector_{x,y}_gradient
103+
size_gradient = lt.gradient.Linear(lt.Remainder.Float)
104+
output['x-size'] = size_gradient.distribute(0.5, 8)
105+
output['y-size'] = size_gradient.distribute(0.5, 8)
106+
107+
output['sets'] = self._do_all_lsc(images)
108+
109+
# \todo Validate images from greyscale camera and force grescale mode
110+
# \todo Debug functionality
111+
112+
return output

0 commit comments

Comments
 (0)