[libcamera-devel] [PATCH 3/5] ipa: rkisp1: Add support of Lens Shading Correction control

paul.elder at ideasonboard.com paul.elder at ideasonboard.com
Tue Jul 12 13:12:50 CEST 2022


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 at 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(),
> +		  &params->others.lsc_config.r_data_tbl[0][0]);
> +	std::copy(grDataTbl_.begin(), grDataTbl_.end(),
> +		  &params->others.lsc_config.gr_data_tbl[0][0]);
> +	std::copy(gbDataTbl_.begin(), gbDataTbl_.end(),
> +		  &params->others.lsc_config.gb_data_tbl[0][0]);
> +	std::copy(bDataTbl_.begin(), bDataTbl_.end(),
> +		  &params->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
> 


More information about the libcamera-devel mailing list