Skip to content

Commit

Permalink
utils: libtuning: modules: Add base LSC module
Browse files Browse the repository at this point in the history
Add a base LSC module to libtuning's collection of modules. It is based
on raspberrypi's ctt's ALSC, but customizable for different lens shading
table sizes, among other things. It alone is insufficient as a module,
but it provides utilities that are useful for and which will simplify
implementing LSC modules.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  • Loading branch information
Rahi374 committed Nov 25, 2022
1 parent b8af250 commit 288cfb9
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
5 changes: 5 additions & 0 deletions utils/tuning/libtuning/modules/lsc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>

from libtuning.modules.lsc.lsc import LSC
72 changes: 72 additions & 0 deletions utils/tuning/libtuning/modules/lsc/lsc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (C) 2019, Raspberry Pi Ltd
# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>

from ..module import Module

import libtuning as lt
import libtuning.utils as utils

import numpy as np


class LSC(Module):
type = 'lsc'
hr_name = 'LSC (Base)'
out_name = 'GenericLSC'

def __init__(self, *,
debug: list,
sector_shape: tuple,
sector_x_gradient: lt.Gradient,
sector_y_gradient: lt.Gradient,
sector_average_function: lt.Average,
smoothing_function: lt.Smoothing):
super().__init__()

self.debug = debug

self.sector_shape = sector_shape
self.sector_x_gradient = sector_x_gradient
self.sector_y_gradient = sector_y_gradient
self.sector_average_function = sector_average_function

self.smoothing_function = smoothing_function

def _enumerate_lsc_images(self, images):
for image in images:
if image.lsc_only:
yield image

def _get_grid(self, channel, img_w, img_h):
# List of number of pixels in each sector
sectors_x = self.sector_x_gradient.distribute(img_w / 2, self.sector_shape[0])
sectors_y = self.sector_y_gradient.distribute(img_h / 2, self.sector_shape[1])

grid = []

r = 0
for y in sectors_y:
c = 0
for x in sectors_x:
grid.append(self.sector_average_function.average(channel[r:r + y, c:c + x]))
c += x
r += y

return np.array(grid)

def _lsc_single_channel(self, channel: np.array,
image: lt.Image, green_grid: np.array = None):
grid = self._get_grid(channel, image.w, image.h)
grid -= image.blacklevel_16
if green_grid is None:
table = np.reshape(1 / grid, self.sector_shape[::-1])
else:
table = np.reshape(green_grid / grid, self.sector_shape[::-1])
table = self.smoothing_function.smoothing(table)

if green_grid is None:
table = table / np.min(table)

return table, grid

0 comments on commit 288cfb9

Please sign in to comment.