summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-09-04 03:57:08 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-09-28 05:41:15 +0300
commit7dc60a5a27f9f97fa78beb7d5a752e0cc88dcf29 (patch)
treece3613dab03bcb1f837fce0b840cb2c31f56bbf1
parentc43c8b1fa0d3dff50b017c33fc8d611a3f1da18e (diff)
ipa: rkisp1: awb: Clamp gains to prevent divisions by zero
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@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--src/ipa/rkisp1/algorithms/awb.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index 59664d09..a3066fbb 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 1.0.
+ */
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