[PATCH v3] ipa: libipa: Change constraint Y target to piecewise linear function

Dan Scally dan.scally at ideasonboard.com
Fri Jun 14 10:55:47 CEST 2024


Hi Paul

On 07/06/2024 08:59, Paul Elder wrote:
> Change the constraint luminance target from a scalar value to a
> piecewise linear function that needs to be sampled by the estimated lux
> value.
>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
For me, the only problem now is that the documentation for parseTuningData() now needs updating, as 
it still suggests a single value for the constraint mode yTarget rather than an array. The rest of 
the patch I think is fine.
> ---
> This patch depends on v5 of "ipa:: Move Pwl from Raspberry Pi"
>
> Changes in v3:
> - use new PointF that's a typedef of Vector
>
> Changes in v2:
> - s/FPoint/PointF/
> - construct default Pwl with *two* points so that it actually constructs
>    properly
> ---
>   src/ipa/libipa/agc_mean_luminance.cpp | 15 +++++++++------
>   src/ipa/libipa/agc_mean_luminance.h   |  4 ++--
>   2 files changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
> index 10c16850d..575143610 100644
> --- a/src/ipa/libipa/agc_mean_luminance.cpp
> +++ b/src/ipa/libipa/agc_mean_luminance.cpp
> @@ -168,8 +168,10 @@ void AgcMeanLuminance::parseConstraint(const YamlObject &modeDict, int32_t id)
>   		AgcConstraint::Bound bound = static_cast<AgcConstraint::Bound>(idx);
>   		double qLo = content["qLo"].get<double>().value_or(0.98);
>   		double qHi = content["qHi"].get<double>().value_or(1.0);
> -		double yTarget =
> -			content["yTarget"].getList<double>().value_or(std::vector<double>{ 0.5 }).at(0);
> +		Pwl yTarget;
> +		int ret = yTarget.readYaml(content["yTarget"]);
> +		if (ret < 0)
> +			yTarget = Pwl({ Pwl::PointF({ 0, 0.5 }), Pwl::PointF({ 1000, 0.5 }) });
>   
>   		AgcConstraint constraint = { bound, qLo, qHi, yTarget };
>   
> @@ -221,7 +223,7 @@ int AgcMeanLuminance::parseConstraintModes(const YamlObject &tuningData)
>   			AgcConstraint::Bound::lower,
>   			0.98,
>   			1.0,
> -			0.5
> +			Pwl({ Pwl::PointF({ 0, 0.5 }), Pwl::PointF({ 1000, 0.5 }) })
>   		};
>   
>   		constraintModes_[controls::ConstraintNormal].insert(
> @@ -471,16 +473,17 @@ double AgcMeanLuminance::estimateInitialGain(double lux) const
>    * \param[in] constraintModeIndex The index of the constraint to adhere to
>    * \param[in] hist A histogram over which to calculate inter-quantile means
>    * \param[in] gain The gain to clamp
> + * \param[in] lux The lux value at which to sample the constraint luminance target pwl
>    *
>    * \return The gain clamped within the constraint bounds
>    */
>   double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex,
>   					     const Histogram &hist,
> -					     double gain)
> +					     double gain, double lux)
>   {
>   	std::vector<AgcConstraint> &constraints = constraintModes_[constraintModeIndex];
>   	for (const AgcConstraint &constraint : constraints) {
> -		double newGain = constraint.yTarget * hist.bins() /
> +		double newGain = constraint.yTarget.eval(constraint.yTarget.domain().clamp(lux)) * hist.bins() /
>   				 hist.interQuantileMean(constraint.qLo, constraint.qHi);
>   
>   		if (constraint.bound == AgcConstraint::Bound::lower &&
> @@ -559,7 +562,7 @@ AgcMeanLuminance::calculateNewEv(uint32_t constraintModeIndex,
>   		exposureModeHelpers_.at(exposureModeIndex);
>   
>   	double gain = estimateInitialGain(lux);
> -	gain = constraintClampGain(constraintModeIndex, yHist, gain);
> +	gain = constraintClampGain(constraintModeIndex, yHist, gain, lux);
>   
>   	/*
>   	 * We don't check whether we're already close to the target, because
> diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
> index 6ec2a0dc9..d43f673dd 100644
> --- a/src/ipa/libipa/agc_mean_luminance.h
> +++ b/src/ipa/libipa/agc_mean_luminance.h
> @@ -38,7 +38,7 @@ public:
>   		Bound bound;
>   		double qLo;
>   		double qHi;
> -		double yTarget;
> +		Pwl yTarget;
>   	};
>   
>   	int parseTuningData(const YamlObject &tuningData);
> @@ -80,7 +80,7 @@ private:
>   	double estimateInitialGain(double lux) const;
>   	double constraintClampGain(uint32_t constraintModeIndex,
>   				   const Histogram &hist,
> -				   double gain);
> +				   double gain, double lux);
>   	utils::Duration filterExposure(utils::Duration exposureValue);
>   
>   	uint64_t frameCount_;


More information about the libcamera-devel mailing list