From patchwork Thu Sep 8 01:41:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17339 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5A384C3272 for ; Thu, 8 Sep 2022 01:43:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1F1566210D; Thu, 8 Sep 2022 03:43:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1662601381; bh=Lpem7NLXtEcHUFpWg1GO9dStYi5oKp1xPNZDA+oPcm4=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=qRO6e/3Fs50wS76cDVmQPbNHzHirOBsVYMfUUXdRD+1uUfsCiGwYsedJalylL/hXQ 9SqSGdwb37dtrkUzwHWy8y6/UlrHlvrqi+5PBrujnYI0TEm0hBqFZ378hOcPt3OhTQ n/dlsvGbelDlCRcpZG/HVmfGmjlx32OQBGNanXmgqv+T/BpAti0hM7dUt/3FojagYR SV3QU3v+F6JWy+Kgh5/ngEJCs7zdVm9HK4VOqA+CJ+d8E3lPcXx2R0jYLLQ8aEMCnv baFMuKLEUzYLP3/g8rJZAxlQlQbfmAKQHUgIMRetvRJbt0WpAXPeuHA792a2NCjhRe j3Xs4UCwQkshg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EBA4F62104 for ; Thu, 8 Sep 2022 03:42:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TItHRTNl"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 68E426CC for ; Thu, 8 Sep 2022 03:42:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1662601379; bh=Lpem7NLXtEcHUFpWg1GO9dStYi5oKp1xPNZDA+oPcm4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TItHRTNlsv7kTY93qvo3RhtILIABoSn5nI9YaRyHqWFVOVF8e+32wte6GHk+Sq+LQ mjPfLgzcsps4D0egttgM8j4RAAbFYGPzln79VUZ985V9mtSSl89ei9yBGHBlVkWJIz By07KW0jVcwgZYHLHGiE0e3fIPFXMHCeVkfoV70w= To: libcamera-devel@lists.libcamera.org Date: Thu, 8 Sep 2022 04:41:58 +0300 Message-Id: <20220908014200.28728-31-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220908014200.28728-1-laurent.pinchart@ideasonboard.com> References: <20220908014200.28728-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 30/32] ipa: rkisp1: awb: Clamp gains to prevent divisions by zero X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- 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. + */ 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