From patchwork Tue Sep 27 02:36:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17442 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 57BEAC327E for ; Tue, 27 Sep 2022 02:37:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1A17C62378; Tue, 27 Sep 2022 04:37:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1664246270; bh=fRiz4PGXGBvt4bzwxnX/+k7/Gm/HEywmgBG7nxHurcQ=; 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=XQoslnuQd53mmVMQo3z2wWu8Pyh5AVhcMj2nZT46Vf43PJh8XSpKIfzSYHcRQ5/2g CSm7XSsWKjomozdxLRjywOjgbOEV/VO6Ao3qjojcj0GzKV0pDslUOyq0wFzTyAmwGK 6vYzHMxquSx0dCA+NZPRSzWilEwqEExGE9zqA7F6Xqyl0Taz/0kuoFZ7Eob4OP+7EL bY/KoJ7f/SNZlgW+/V8dtOvzh+q2Lp+WKMQiVRO9i+Bzu9rg7p7RQsR/qvwLWAM1Xh IOdDpu7EN7VQh1H8URVtT40md4ZKPfpE6VsXXnDDuufIgjyYFfBjxCJOugtc1x+JQc zL9MdHfDUsPzg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0D7CE62295 for ; Tue, 27 Sep 2022 04:37:48 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="G+jS83vt"; 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 85A42E5 for ; Tue, 27 Sep 2022 04:37:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1664246267; bh=fRiz4PGXGBvt4bzwxnX/+k7/Gm/HEywmgBG7nxHurcQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=G+jS83vt+79paWYUyP4UxddnXA+P6yDBONwajEyPM0/GBbYHGBzKWcF5/OOESkNUX lWEzb1hNgLsPZJyEgOMYAUWRQIVxNCB5SQbmzuJnkGy4X6vqW3fQ3JbEiLYtiaMbqO 8Xh/UZHWysFBr1jJqalBo6qX4fR3r5GxE4/AQ3f0= To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Sep 2022 05:36:40 +0300 Message-Id: <20220927023642.12341-32-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220927023642.12341-1-laurent.pinchart@ideasonboard.com> References: <20220927023642.12341-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 31/33] 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 --- Changes since v4: - Fix typo in comment --- 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 59664d09b84c..a3066fbb1994 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