Message ID | 20220622151918.451635-4-fsylvestre@baylibre.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Florian, On Wed, Jun 22, 2022 at 05:19:16PM +0200, Florian Sylvestre via libcamera-devel wrote: > The Lens Shading Correction algorithm applies a correction on the pixels based > on values defined in the YAML tuning file. > > Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com> Same comments as the patch on GSL. Paul > --- > src/ipa/rkisp1/algorithms/lsc.cpp | 171 ++++++++++++++++++++++++++ > src/ipa/rkisp1/algorithms/lsc.h | 44 +++++++ > src/ipa/rkisp1/algorithms/meson.build | 1 + > src/ipa/rkisp1/data/ov5640.yaml | 81 ++++++++++++ > src/ipa/rkisp1/rkisp1.cpp | 1 + > 5 files changed, 298 insertions(+) > create mode 100644 src/ipa/rkisp1/algorithms/lsc.cpp > create mode 100644 src/ipa/rkisp1/algorithms/lsc.h > > diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp > new file mode 100644 > index 00000000..f68243a1 > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/lsc.cpp > @@ -0,0 +1,171 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021-2022, Ideas On Board > + * > + * lsc.cpp - RkISP1 Lens Shading Correction control > + */ > + > +#include "lsc.h" > + > +#include <libcamera/base/log.h> > + > +#include "libcamera/internal/yaml_parser.h" > +#include "linux/rkisp1-config.h" > + > +/** > + * \file lsc.h > + */ > + > +namespace libcamera { > + > +namespace ipa::rkisp1::algorithms { > + > +/** > + * \class LensShadingCorrection > + * \brief RkISP1 Lens Shading Correction control > + * > + * Due to the optical characteristics of the lens, the light intensity received > + * by the sensor is not uniform. > + * > + * The Lens Shading Correction algorithm applies a correction on the pixels for > + * each component based on measurement done during the camera tuning process. > + */ > + > +LOG_DEFINE_CATEGORY(RkISP1Lsc) > + > +LensShadingCorrection::LensShadingCorrection() > + : tuningParameters_(false) > +{ > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::init > + */ > +int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, > + const YamlObject &tuningData) > +{ > + xSizeTbl_ = tuningData["x-size"].getList<uint16_t>(); > + if (xSizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'x-size'" > + << "in tuning file (list size:" > + << xSizeTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > + return -EINVAL; > + } > + > + ySizeTbl_ = tuningData["y-size"].getList<uint16_t>(); > + if (ySizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'y-size'" > + << "in tuning file (list size:" > + << ySizeTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > + return -EINVAL; > + } > + > + xGradTbl_ = tuningData["x-grad"].getList<uint16_t>(); > + if (xGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'x-grad'" > + << "in tuning file (list size:" > + << xGradTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > + return -EINVAL; > + } > + > + yGradTbl_ = tuningData["y-grad"].getList<uint16_t>(); > + if (yGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'y-grad'" > + << "in tuning file (list size:" > + << yGradTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > + return -EINVAL; > + } > + > + rDataTbl_ = tuningData["r"].getList<uint16_t>(); > + if (rDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'r'" > + << "in tuning file (list size:" > + << rDataTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > + return -EINVAL; > + } > + > + grDataTbl_ = tuningData["gr"].getList<uint16_t>(); > + if (grDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'gr'" > + << "in tuning file (list size:" > + << grDataTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > + return -EINVAL; > + } > + > + gbDataTbl_ = tuningData["gb"].getList<uint16_t>(); > + if (gbDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'gb'" > + << "in tuning file (list size:" > + << gbDataTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > + return -EINVAL; > + } > + > + bDataTbl_ = tuningData["b"].getList<uint16_t>(); > + if (bDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > + LOG(RkISP1Lsc, Error) > + << "Issue while parsing 'b'" > + << "in tuning file (list size:" > + << bDataTbl_.size() << "/" > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > + return -EINVAL; > + } > + > + tuningParameters_ = true; > + > + return 0; > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::prepare > + */ > +void LensShadingCorrection::prepare(IPAContext &context, > + rkisp1_params_cfg *params) > +{ > + if (context.frameContext.frameCount > 0) > + return; > + > + if (!tuningParameters_) > + return; > + > + std::copy(xSizeTbl_.begin(), xSizeTbl_.end(), > + params->others.lsc_config.x_size_tbl); > + std::copy(ySizeTbl_.begin(), ySizeTbl_.end(), > + params->others.lsc_config.y_size_tbl); > + std::copy(xGradTbl_.begin(), xGradTbl_.end(), > + params->others.lsc_config.x_grad_tbl); > + std::copy(yGradTbl_.begin(), yGradTbl_.end(), > + params->others.lsc_config.y_grad_tbl); > + > + std::copy(rDataTbl_.begin(), rDataTbl_.end(), > + ¶ms->others.lsc_config.r_data_tbl[0][0]); > + std::copy(grDataTbl_.begin(), grDataTbl_.end(), > + ¶ms->others.lsc_config.gr_data_tbl[0][0]); > + std::copy(gbDataTbl_.begin(), gbDataTbl_.end(), > + ¶ms->others.lsc_config.gb_data_tbl[0][0]); > + std::copy(bDataTbl_.begin(), bDataTbl_.end(), > + ¶ms->others.lsc_config.b_data_tbl[0][0]); > + > + params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC; > + params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC; > + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC; > +} > + > +REGISTER_IPA_ALGORITHM(LensShadingCorrection) > + > +} /* namespace ipa::rkisp1::algorithms */ > + > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h > new file mode 100644 > index 00000000..7f620ffa > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/lsc.h > @@ -0,0 +1,44 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021-2022, Ideas On Board > + * > + * gsl.h - RkISP1 Lens Shading Correction control > + */ > + > +#pragma once > + > +#include <linux/rkisp1-config.h> > + > +#include "algorithm.h" > + > +namespace libcamera { > + > +struct IPACameraSensorInfo; > + > +namespace ipa::rkisp1::algorithms { > + > +class LensShadingCorrection : public Algorithm > +{ > +public: > + LensShadingCorrection(); > + ~LensShadingCorrection() = default; > + > + int init(IPAContext &context, const YamlObject &tuningData) override; > + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; > + > +private: > + bool tuningParameters_; > + > + std::vector<uint16_t> rDataTbl_; > + std::vector<uint16_t> grDataTbl_; > + std::vector<uint16_t> gbDataTbl_; > + std::vector<uint16_t> bDataTbl_; > + > + std::vector<uint16_t> xGradTbl_; > + std::vector<uint16_t> yGradTbl_; > + std::vector<uint16_t> xSizeTbl_; > + std::vector<uint16_t> ySizeTbl_; > +}; > + > +} /* namespace ipa::rkisp1::algorithms */ > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build > index 0597c353..64e11dce 100644 > --- a/src/ipa/rkisp1/algorithms/meson.build > +++ b/src/ipa/rkisp1/algorithms/meson.build > @@ -5,4 +5,5 @@ rkisp1_ipa_algorithms = files([ > 'awb.cpp', > 'blc.cpp', > 'gsl.cpp', > + 'lsc.cpp', > ]) > diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml > index 6cb84ed9..154ed3b5 100644 > --- a/src/ipa/rkisp1/data/ov5640.yaml > +++ b/src/ipa/rkisp1/data/ov5640.yaml > @@ -16,4 +16,85 @@ algorithms: > red: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > green: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > blue: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > + - LensShadingCorrection: > + x-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] > + y-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] > + x-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] > + y-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] > + r: [ > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + ] > + gr: [ > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + ] > + gb: [ > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + ] > + b: [ > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + ] > ... > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp > index 622a0d61..996edc0a 100644 > --- a/src/ipa/rkisp1/rkisp1.cpp > +++ b/src/ipa/rkisp1/rkisp1.cpp > @@ -32,6 +32,7 @@ > #include "algorithms/awb.h" > #include "algorithms/blc.h" > #include "algorithms/gsl.h" > +#include "algorithms/lsc.h" > #include "libipa/camera_sensor_helper.h" > > #include "ipa_context.h" > -- > 2.34.1 >
Hello, On Tue, Jul 12, 2022 at 08:12:50PM +0900, Paul Elder via libcamera-devel wrote: > On Wed, Jun 22, 2022 at 05:19:16PM +0200, Florian Sylvestre via libcamera-devel wrote: > > The Lens Shading Correction algorithm applies a correction on the pixels based > > on values defined in the YAML tuning file. > > > > Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com> > > Same comments as the patch on GSL. Ditto, plus a few comments below. > > --- > > src/ipa/rkisp1/algorithms/lsc.cpp | 171 ++++++++++++++++++++++++++ > > src/ipa/rkisp1/algorithms/lsc.h | 44 +++++++ > > src/ipa/rkisp1/algorithms/meson.build | 1 + > > src/ipa/rkisp1/data/ov5640.yaml | 81 ++++++++++++ > > src/ipa/rkisp1/rkisp1.cpp | 1 + > > 5 files changed, 298 insertions(+) > > create mode 100644 src/ipa/rkisp1/algorithms/lsc.cpp > > create mode 100644 src/ipa/rkisp1/algorithms/lsc.h > > > > diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp > > new file mode 100644 > > index 00000000..f68243a1 > > --- /dev/null > > +++ b/src/ipa/rkisp1/algorithms/lsc.cpp > > @@ -0,0 +1,171 @@ > > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > > +/* > > + * Copyright (C) 2021-2022, Ideas On Board > > + * > > + * lsc.cpp - RkISP1 Lens Shading Correction control > > + */ > > + > > +#include "lsc.h" > > + > > +#include <libcamera/base/log.h> > > + > > +#include "libcamera/internal/yaml_parser.h" > > +#include "linux/rkisp1-config.h" > > + > > +/** > > + * \file lsc.h > > + */ > > + > > +namespace libcamera { > > + > > +namespace ipa::rkisp1::algorithms { > > + > > +/** > > + * \class LensShadingCorrection > > + * \brief RkISP1 Lens Shading Correction control > > + * > > + * Due to the optical characteristics of the lens, the light intensity received > > + * by the sensor is not uniform. > > + * > > + * The Lens Shading Correction algorithm applies a correction on the pixels for > > + * each component based on measurement done during the camera tuning process. > > + */ > > + > > +LOG_DEFINE_CATEGORY(RkISP1Lsc) > > + > > +LensShadingCorrection::LensShadingCorrection() > > + : tuningParameters_(false) > > +{ > > +} > > + > > +/** > > + * \copydoc libcamera::ipa::Algorithm::init > > + */ > > +int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, > > + const YamlObject &tuningData) > > +{ > > + xSizeTbl_ = tuningData["x-size"].getList<uint16_t>(); > > + if (xSizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'x-size'" > > + << "in tuning file (list size:" > > + << xSizeTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > > + return -EINVAL; > > + } > > + > > + ySizeTbl_ = tuningData["y-size"].getList<uint16_t>(); > > + if (ySizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'y-size'" > > + << "in tuning file (list size:" > > + << ySizeTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > > + return -EINVAL; > > + } > > + > > + xGradTbl_ = tuningData["x-grad"].getList<uint16_t>(); > > + if (xGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'x-grad'" > > + << "in tuning file (list size:" > > + << xGradTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > > + return -EINVAL; > > + } The gradients are directly derived from the sector sizes and should thus be computed in the LensShadingCorrection::prepare() function instead of loaded from the tuning data. Please see below > > + > > + yGradTbl_ = tuningData["y-grad"].getList<uint16_t>(); > > + if (yGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'y-grad'" > > + << "in tuning file (list size:" > > + << yGradTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; > > + return -EINVAL; > > + } > > + > > + rDataTbl_ = tuningData["r"].getList<uint16_t>(); > > + if (rDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'r'" > > + << "in tuning file (list size:" > > + << rDataTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > > + return -EINVAL; > > + } > > + > > + grDataTbl_ = tuningData["gr"].getList<uint16_t>(); > > + if (grDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'gr'" > > + << "in tuning file (list size:" > > + << grDataTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > > + return -EINVAL; > > + } > > + > > + gbDataTbl_ = tuningData["gb"].getList<uint16_t>(); > > + if (gbDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'gb'" > > + << "in tuning file (list size:" > > + << gbDataTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > > + return -EINVAL; > > + } > > + > > + bDataTbl_ = tuningData["b"].getList<uint16_t>(); > > + if (bDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { > > + LOG(RkISP1Lsc, Error) > > + << "Issue while parsing 'b'" > > + << "in tuning file (list size:" > > + << bDataTbl_.size() << "/" > > + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; > > + return -EINVAL; > > + } > > + > > + tuningParameters_ = true; > > + > > + return 0; > > +} > > + > > +/** > > + * \copydoc libcamera::ipa::Algorithm::prepare > > + */ > > +void LensShadingCorrection::prepare(IPAContext &context, > > + rkisp1_params_cfg *params) > > +{ > > + if (context.frameContext.frameCount > 0) > > + return; > > + > > + if (!tuningParameters_) > > + return; > > + > > + std::copy(xSizeTbl_.begin(), xSizeTbl_.end(), > > + params->others.lsc_config.x_size_tbl); > > + std::copy(ySizeTbl_.begin(), ySizeTbl_.end(), > > + params->others.lsc_config.y_size_tbl); > > + std::copy(xGradTbl_.begin(), xGradTbl_.end(), > > + params->others.lsc_config.x_grad_tbl); > > + std::copy(yGradTbl_.begin(), yGradTbl_.end(), > > + params->others.lsc_config.y_grad_tbl); The gradient value must be equal to grad = round(32768 / size) in both the X and Y directions. > > + > > + std::copy(rDataTbl_.begin(), rDataTbl_.end(), > > + ¶ms->others.lsc_config.r_data_tbl[0][0]); > > + std::copy(grDataTbl_.begin(), grDataTbl_.end(), > > + ¶ms->others.lsc_config.gr_data_tbl[0][0]); > > + std::copy(gbDataTbl_.begin(), gbDataTbl_.end(), > > + ¶ms->others.lsc_config.gb_data_tbl[0][0]); > > + std::copy(bDataTbl_.begin(), bDataTbl_.end(), > > + ¶ms->others.lsc_config.b_data_tbl[0][0]); > > + > > + params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC; > > + params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC; > > + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC; > > +} > > + > > +REGISTER_IPA_ALGORITHM(LensShadingCorrection) > > + > > +} /* namespace ipa::rkisp1::algorithms */ > > + > > +} /* namespace libcamera */ > > diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h > > new file mode 100644 > > index 00000000..7f620ffa > > --- /dev/null > > +++ b/src/ipa/rkisp1/algorithms/lsc.h > > @@ -0,0 +1,44 @@ > > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > > +/* > > + * Copyright (C) 2021-2022, Ideas On Board > > + * > > + * gsl.h - RkISP1 Lens Shading Correction control > > + */ > > + > > +#pragma once > > + > > +#include <linux/rkisp1-config.h> > > + > > +#include "algorithm.h" > > + > > +namespace libcamera { > > + > > +struct IPACameraSensorInfo; > > + > > +namespace ipa::rkisp1::algorithms { > > + > > +class LensShadingCorrection : public Algorithm > > +{ > > +public: > > + LensShadingCorrection(); > > + ~LensShadingCorrection() = default; > > + > > + int init(IPAContext &context, const YamlObject &tuningData) override; > > + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; > > + > > +private: > > + bool tuningParameters_; > > + > > + std::vector<uint16_t> rDataTbl_; > > + std::vector<uint16_t> grDataTbl_; > > + std::vector<uint16_t> gbDataTbl_; > > + std::vector<uint16_t> bDataTbl_; > > + > > + std::vector<uint16_t> xGradTbl_; > > + std::vector<uint16_t> yGradTbl_; > > + std::vector<uint16_t> xSizeTbl_; > > + std::vector<uint16_t> ySizeTbl_; I would drop all the Tbl_ suffixes. > > +}; > > + > > +} /* namespace ipa::rkisp1::algorithms */ > > +} /* namespace libcamera */ > > diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build > > index 0597c353..64e11dce 100644 > > --- a/src/ipa/rkisp1/algorithms/meson.build > > +++ b/src/ipa/rkisp1/algorithms/meson.build > > @@ -5,4 +5,5 @@ rkisp1_ipa_algorithms = files([ > > 'awb.cpp', > > 'blc.cpp', > > 'gsl.cpp', > > + 'lsc.cpp', > > ]) > > diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml > > index 6cb84ed9..154ed3b5 100644 > > --- a/src/ipa/rkisp1/data/ov5640.yaml > > +++ b/src/ipa/rkisp1/data/ov5640.yaml > > @@ -16,4 +16,85 @@ algorithms: > > red: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > > green: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > > blue: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] > > + - LensShadingCorrection: > > + x-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] > > + y-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] I'm afraid this won't work. The sizes express how the image is divided in a grid of 16x16 blocks (as the grid mus be symmetrical around the frame centre, they're specified as 8 values instead of 16). The values must thus be computed dynamically based on the frame size, with the sum of all the sizes horizontally and vertically being exactly equal to half of the image width and height respectively. You could store relative sizes in the configuration file, for instance as floating point numbers, with the constraint that the sum must be equal to 0.5 and then multiply these values by the image width when configuring the ISP. Alternatively, you can also use fixed-by values. For this configuration file, I would start with giving all the cells an identical size. > > + x-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] > > + y-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] > > + r: [ > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, The values surprise me, as they're expressed on 12 bits with 2 bits of integral part and 10 bits of fractional part, with valid values in the range [1, 3.999]. I would thus expect all values here to be set to 1024 (we could also store floating-point values, but that would increase the processing time during initialization, I don't think it would be useful). > > + ] > > + gr: [ > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + ] > > + gb: [ > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + ] > > + b: [ > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > > + ] > > ... > > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp > > index 622a0d61..996edc0a 100644 > > --- a/src/ipa/rkisp1/rkisp1.cpp > > +++ b/src/ipa/rkisp1/rkisp1.cpp > > @@ -32,6 +32,7 @@ > > #include "algorithms/awb.h" > > #include "algorithms/blc.h" > > #include "algorithms/gsl.h" > > +#include "algorithms/lsc.h" > > #include "libipa/camera_sensor_helper.h" > > > > #include "ipa_context.h"
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp new file mode 100644 index 00000000..f68243a1 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/lsc.cpp @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * lsc.cpp - RkISP1 Lens Shading Correction control + */ + +#include "lsc.h" + +#include <libcamera/base/log.h> + +#include "libcamera/internal/yaml_parser.h" +#include "linux/rkisp1-config.h" + +/** + * \file lsc.h + */ + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +/** + * \class LensShadingCorrection + * \brief RkISP1 Lens Shading Correction control + * + * Due to the optical characteristics of the lens, the light intensity received + * by the sensor is not uniform. + * + * The Lens Shading Correction algorithm applies a correction on the pixels for + * each component based on measurement done during the camera tuning process. + */ + +LOG_DEFINE_CATEGORY(RkISP1Lsc) + +LensShadingCorrection::LensShadingCorrection() + : tuningParameters_(false) +{ +} + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, + const YamlObject &tuningData) +{ + xSizeTbl_ = tuningData["x-size"].getList<uint16_t>(); + if (xSizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'x-size'" + << "in tuning file (list size:" + << xSizeTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; + return -EINVAL; + } + + ySizeTbl_ = tuningData["y-size"].getList<uint16_t>(); + if (ySizeTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'y-size'" + << "in tuning file (list size:" + << ySizeTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; + return -EINVAL; + } + + xGradTbl_ = tuningData["x-grad"].getList<uint16_t>(); + if (xGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'x-grad'" + << "in tuning file (list size:" + << xGradTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; + return -EINVAL; + } + + yGradTbl_ = tuningData["y-grad"].getList<uint16_t>(); + if (yGradTbl_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'y-grad'" + << "in tuning file (list size:" + << yGradTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << ")"; + return -EINVAL; + } + + rDataTbl_ = tuningData["r"].getList<uint16_t>(); + if (rDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'r'" + << "in tuning file (list size:" + << rDataTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; + return -EINVAL; + } + + grDataTbl_ = tuningData["gr"].getList<uint16_t>(); + if (grDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'gr'" + << "in tuning file (list size:" + << grDataTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; + return -EINVAL; + } + + gbDataTbl_ = tuningData["gb"].getList<uint16_t>(); + if (gbDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'gb'" + << "in tuning file (list size:" + << gbDataTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; + return -EINVAL; + } + + bDataTbl_ = tuningData["b"].getList<uint16_t>(); + if (bDataTbl_.size() != RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX) { + LOG(RkISP1Lsc, Error) + << "Issue while parsing 'b'" + << "in tuning file (list size:" + << bDataTbl_.size() << "/" + << RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX << ")"; + return -EINVAL; + } + + tuningParameters_ = true; + + return 0; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void LensShadingCorrection::prepare(IPAContext &context, + rkisp1_params_cfg *params) +{ + if (context.frameContext.frameCount > 0) + return; + + if (!tuningParameters_) + return; + + std::copy(xSizeTbl_.begin(), xSizeTbl_.end(), + params->others.lsc_config.x_size_tbl); + std::copy(ySizeTbl_.begin(), ySizeTbl_.end(), + params->others.lsc_config.y_size_tbl); + std::copy(xGradTbl_.begin(), xGradTbl_.end(), + params->others.lsc_config.x_grad_tbl); + std::copy(yGradTbl_.begin(), yGradTbl_.end(), + params->others.lsc_config.y_grad_tbl); + + std::copy(rDataTbl_.begin(), rDataTbl_.end(), + ¶ms->others.lsc_config.r_data_tbl[0][0]); + std::copy(grDataTbl_.begin(), grDataTbl_.end(), + ¶ms->others.lsc_config.gr_data_tbl[0][0]); + std::copy(gbDataTbl_.begin(), gbDataTbl_.end(), + ¶ms->others.lsc_config.gb_data_tbl[0][0]); + std::copy(bDataTbl_.begin(), bDataTbl_.end(), + ¶ms->others.lsc_config.b_data_tbl[0][0]); + + params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC; + params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC; + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC; +} + +REGISTER_IPA_ALGORITHM(LensShadingCorrection) + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h new file mode 100644 index 00000000..7f620ffa --- /dev/null +++ b/src/ipa/rkisp1/algorithms/lsc.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * gsl.h - RkISP1 Lens Shading Correction control + */ + +#pragma once + +#include <linux/rkisp1-config.h> + +#include "algorithm.h" + +namespace libcamera { + +struct IPACameraSensorInfo; + +namespace ipa::rkisp1::algorithms { + +class LensShadingCorrection : public Algorithm +{ +public: + LensShadingCorrection(); + ~LensShadingCorrection() = default; + + int init(IPAContext &context, const YamlObject &tuningData) override; + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; + +private: + bool tuningParameters_; + + std::vector<uint16_t> rDataTbl_; + std::vector<uint16_t> grDataTbl_; + std::vector<uint16_t> gbDataTbl_; + std::vector<uint16_t> bDataTbl_; + + std::vector<uint16_t> xGradTbl_; + std::vector<uint16_t> yGradTbl_; + std::vector<uint16_t> xSizeTbl_; + std::vector<uint16_t> ySizeTbl_; +}; + +} /* namespace ipa::rkisp1::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index 0597c353..64e11dce 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -5,4 +5,5 @@ rkisp1_ipa_algorithms = files([ 'awb.cpp', 'blc.cpp', 'gsl.cpp', + 'lsc.cpp', ]) diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml index 6cb84ed9..154ed3b5 100644 --- a/src/ipa/rkisp1/data/ov5640.yaml +++ b/src/ipa/rkisp1/data/ov5640.yaml @@ -16,4 +16,85 @@ algorithms: red: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] green: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] blue: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096 ] + - LensShadingCorrection: + x-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] + y-size: [ 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 ] + x-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + y-grad: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + r: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + gr: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + gb: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + b: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] ... diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 622a0d61..996edc0a 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -32,6 +32,7 @@ #include "algorithms/awb.h" #include "algorithms/blc.h" #include "algorithms/gsl.h" +#include "algorithms/lsc.h" #include "libipa/camera_sensor_helper.h" #include "ipa_context.h"
The Lens Shading Correction algorithm applies a correction on the pixels based on values defined in the YAML tuning file. Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com> --- src/ipa/rkisp1/algorithms/lsc.cpp | 171 ++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/lsc.h | 44 +++++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/data/ov5640.yaml | 81 ++++++++++++ src/ipa/rkisp1/rkisp1.cpp | 1 + 5 files changed, 298 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/lsc.cpp create mode 100644 src/ipa/rkisp1/algorithms/lsc.h