From patchwork Wed Sep 2 09:07:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 28163 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 BFA48C3344 for ; Wed, 2 Sep 2026 09:07:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1605F685C4; Wed, 2 Sep 2026 11:07:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LGpMTTiu"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BBA926859C for ; Wed, 2 Sep 2026 11:07:34 +0200 (CEST) Received: from [127.0.1.1] (chfd-03-b2-v4wan-176392-cust229.vm15.cable.virginm.net [82.19.20.230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 53B0224BD; Wed, 2 Sep 2026 11:06:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1788339963; bh=G/ZKVxtkM0vGyVqWxm9UpzmxbA7RUcEeTxMnnIFJQyw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LGpMTTiu5y5giPmR+oacQklP+NhP8gksl0eE9MHmPHvY+hF2LjkDkK2PUCePSQL99 GNni1VcFPIsGRb1dbbkjGhhqg6ZKOgy/DqwSpLm63qKCtcAdJCZocMQgjFeKqa1fcz 9+m9qcahNGRdAu3QgQPuHWC+7nJ1yZYPKhpAvb54= From: Daniel Scally Date: Wed, 02 Sep 2026 10:07:19 +0100 Subject: [PATCH v3 01/10] libipa: awb_grey: Correct minimum gain clamping MIME-Version: 1.0 Message-Id: <20260902-ipu3-libipa-rework-v3-1-b7da9b062326@ideasonboard.com> References: <20260902-ipu3-libipa-rework-v3-0-b7da9b062326@ideasonboard.com> In-Reply-To: <20260902-ipu3-libipa-rework-v3-0-b7da9b062326@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1937; i=dan.scally@ideasonboard.com; h=from:subject:message-id; bh=G/ZKVxtkM0vGyVqWxm9UpzmxbA7RUcEeTxMnnIFJQyw=; b=owEBbQKS/ZANAwAKAchJV3psRXUyAcsmYgBql+dTX6mQrSVaMQ2AwMGYBshSpPN2jmfM6PqU0 gJ3/xuo9CmJAjMEAAEKAB0WIQQqyuwyDnZdb+mxmm/ISVd6bEV1MgUCapfnUwAKCRDISVd6bEV1 MrjxD/9bDPxFZ9xYIGSp7Gm3rUTYVqM4EqxkfeSk0VzjoYeU4SkJUJ3rV3va16xkiJ5o9Hh3U8g GLG5sOYD8Ll18BjCLM1EbHg4dbrKgLh/s+U1VgppMRKOYAg1Em69xmGCgu9ujuQF0XTj9/v9KR3 DxKZ/5+0sD/s7YIw/OfGBc66dHpUMC+uunMvoLeYRnxS40hvJWW3ReQiCg3r6TokJomo9gNWvN+ IhGGoxMMBMP1FRvqs+Pt/8auP3VRBaT2rYMQFzUXjf+9aQpaYodbSqvpO9gDTn0NpCNdu3drupW hWAxbxMZ905haXpmrzCHEdK23+Kx9SwCg4X6iim40a5I75uoGEORlt2c1UW/EaagmVY/I2HS7PT hykeNjoTGpfDfxOm3xgEE9M9uMK6i9spWv9PLjiHbm6D9vOLyhNQCEPn1bM9zWrw/9NP4GOdbcB YTPOW3sm5ADE3bupXSlw8WSYOnJxuWkPb9N5HBYmxBQOdxFGnGdME8r4x6TR96gM+BqLohgaN/E ocIc/C6PUCM7jyQ3U2yPby91FvFBdy5X+iAcws0+kRSEsoDqpAw8kHQQC08ifDI/swdGQGRaZPq VLjpgT5rCtZxHvPYaWgrZ2EFhAKvXbdNLHRMWF1P6T1Ab7i/zn4U40lJc4UwsOCC4/N2CiQScd+ JlO23xi/walGfgg== X-Developer-Key: i=dan.scally@ideasonboard.com; a=openpgp; fpr=EEC699ACA1B7CB5D31330C0BBD501C2A3546CCF6 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- 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; }