[v4,01/10] libipa: awb_grey: Correct minimum gain clamping
diff mbox series

Message ID 20260914-ipu3-libipa-rework-v4-1-ff8ee2d3dd24@ideasonboard.com
State New
Headers show
Series
  • libipa: Re-work IPU3 IPA to use libipa algorithms
Related show

Commit Message

Dan Scally Sept. 14, 2026, 2:53 p.m. UTC
The AwbGrey algorithm currently calculates Red and Blue gains by
dividing the observed mean green by the observed mean red or blue
value, clamped to 1.0. The documentation for AwbStats::rgbMeans()
says:

  Fetch the RGB means from the statistics. The values of each channel
  are dimensionless and only the ratios are used for further
  calculations. This is used by the simple grey world model to
  calculate the gains to apply.

  \todo Make a requirement to return statistics in the [0, 1] range.

This requirement that the means be within the [0, 1] range is at odds
with the clamping, as it means that all values will be clamped to 1.0
and so the gains will always all be 1.0.

Change the clamp to be to 0.001, which still fulfills the goal of
preventing divide-by-zero errors whilst allowing means in the range
[0, 1].

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>

---
Changes in v4:

	- None

Changes in v3:

	- New patch
---
 src/ipa/libipa/awb_grey.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Kieran Bingham Sept. 14, 2026, 3:49 p.m. UTC | #1
Quoting Daniel Scally (2026-09-14 15:53:41)
> The AwbGrey algorithm currently calculates Red and Blue gains by
> dividing the observed mean green by the observed mean red or blue
> value, clamped to 1.0. The documentation for AwbStats::rgbMeans()
> says:
> 
>   Fetch the RGB means from the statistics. The values of each channel
>   are dimensionless and only the ratios are used for further
>   calculations. This is used by the simple grey world model to
>   calculate the gains to apply.
> 
>   \todo Make a requirement to return statistics in the [0, 1] range.
> 
> This requirement that the means be within the [0, 1] range is at odds
> with the clamping, as it means that all values will be clamped to 1.0
> and so the gains will always all be 1.0.
> 
> Change the clamp to be to 0.001, which still fulfills the goal of
> preventing divide-by-zero errors whilst allowing means in the range
> [0, 1].
> 
> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>

Does this impact all platforms currently ? Or only the upcoming IPU3
implementation?

Anyway I think it makes sense so:

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

> 
> ---
> Changes in v4:
> 
>         - None
> 
> Changes in v3:
> 
>         - New patch
> ---
>  src/ipa/libipa/awb_grey.cpp | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/src/ipa/libipa/awb_grey.cpp b/src/ipa/libipa/awb_grey.cpp
> index b1222902388393aa24dbebd6f466cc6d6389fcdc..9ca9b5a587dbce6d02765a07f1da3c782d713555 100644
> --- a/src/ipa/libipa/awb_grey.cpp
> +++ b/src/ipa/libipa/awb_grey.cpp
> @@ -82,11 +82,11 @@ AwbGrey::calculateAwb(const AwbStats &stats, [[maybe_unused]] unsigned int lux,
>         /*
>          * Estimate the red and blue gains to apply in a grey world. The green
>          * gain is hardcoded to 1.0. Avoid divisions by zero by clamping the
> -        * divisor to a minimum value of 1.0.
> +        * divisor to a minimum value of 0.001.
>          */
> -       result.gains.r() = means.g() / std::max(means.r(), 1.0);
> +       result.gains.r() = means.g() / std::max(means.r(), 0.001);
>         result.gains.g() = 1.0;
> -       result.gains.b() = means.g() / std::max(means.b(), 1.0);
> +       result.gains.b() = means.g() / std::max(means.b(), 0.001);
>         return result;
>  }
>  
> 
> -- 
> 2.43.0
>

Patch
diff mbox series

diff --git a/src/ipa/libipa/awb_grey.cpp b/src/ipa/libipa/awb_grey.cpp
index b1222902388393aa24dbebd6f466cc6d6389fcdc..9ca9b5a587dbce6d02765a07f1da3c782d713555 100644
--- a/src/ipa/libipa/awb_grey.cpp
+++ b/src/ipa/libipa/awb_grey.cpp
@@ -82,11 +82,11 @@  AwbGrey::calculateAwb(const AwbStats &stats, [[maybe_unused]] unsigned int lux,
 	/*
 	 * Estimate the red and blue gains to apply in a grey world. The green
 	 * gain is hardcoded to 1.0. Avoid divisions by zero by clamping the
-	 * divisor to a minimum value of 1.0.
+	 * divisor to a minimum value of 0.001.
 	 */
-	result.gains.r() = means.g() / std::max(means.r(), 1.0);
+	result.gains.r() = means.g() / std::max(means.r(), 0.001);
 	result.gains.g() = 1.0;
-	result.gains.b() = means.g() / std::max(means.b(), 1.0);
+	result.gains.b() = means.g() / std::max(means.b(), 0.001);
 	return result;
 }