[libcamera-devel] [PATCH v4 30/32] ipa: rkisp1: awb: Clamp gains to prevent divisions by zero

Kieran Bingham kieran.bingham at ideasonboard.com
Wed Sep 21 01:41:24 CEST 2022


Quoting Laurent Pinchart via libcamera-devel (2022-09-08 02:41:58)
> The gain values are currently clamped to the range [0.0, 3.996] used by
> the hardware. A zero value makes little sense, as it would completely
> remove the contribution of the corresponding color channel from the AWB
> accumulators, but worse, would lead to divisions by zero when
> calculating the raw means in subsequent iterations. Prevent this by
> setting the minimum gain value to 1/256.
> 
> While at it, clamp the gain values before filtering them, to improve the
> stability of the control loop.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
>  src/ipa/rkisp1/algorithms/awb.cpp | 22 +++++++++++++++-------
>  1 file changed, 15 insertions(+), 7 deletions(-)
> 
> diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
> index de54c4d24650..5f2535688c93 100644
> --- a/src/ipa/rkisp1/algorithms/awb.cpp
> +++ b/src/ipa/rkisp1/algorithms/awb.cpp
> @@ -265,21 +265,29 @@ void Awb::process(IPAContext &context,
>  
>         frameContext.awb.temperatureK = estimateCCT(redMean, greenMean, blueMean);
>  
> -       /* Estimate the red and blue gains to apply in a grey world. */
> +       /*
> +        * Estimate the red and blue gains to apply in a grey world. The green
> +        * gain is hardcoded to 0.

0 or 1?

With that 

Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

> +        */
>         double redGain = greenMean / (redMean + 1);
>         double blueGain = greenMean / (blueMean + 1);
>  
> +       /*
> +        * Clamp the gain values to the hardware, which expresses gains as Q2.8
> +        * unsigned integer values. Set the minimum just above zero to avoid
> +        * divisions by zero when computing the raw means in subsequent
> +        * iterations.
> +        */
> +       redGain = std::clamp(redGain, 1.0 / 256, 1023.0 / 256);
> +       blueGain = std::clamp(blueGain, 1.0 / 256, 1023.0 / 256);
> +
>         /* Filter the values to avoid oscillations. */
>         double speed = 0.2;
>         redGain = speed * redGain + (1 - speed) * activeState.awb.gains.automatic.red;
>         blueGain = speed * blueGain + (1 - speed) * activeState.awb.gains.automatic.blue;
>  
> -       /*
> -        * Gain values are unsigned integer value, range 0 to 4 with 8 bit
> -        * fractional part. Hardcode the green gain to 1.0.
> -        */
> -       activeState.awb.gains.automatic.red = std::clamp(redGain, 0.0, 1023.0 / 256);
> -       activeState.awb.gains.automatic.blue = std::clamp(blueGain, 0.0, 1023.0 / 256);
> +       activeState.awb.gains.automatic.red = redGain;
> +       activeState.awb.gains.automatic.blue = blueGain;
>         activeState.awb.gains.automatic.green = 1.0;
>  
>         LOG(RkISP1Awb, Debug) << std::showpoint
> -- 
> Regards,
> 
> Laurent Pinchart
>


More information about the libcamera-devel mailing list