From patchwork Mon Sep 14 14:53:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 28287 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 65814C3200 for ; Mon, 14 Sep 2026 14:54:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 29767686C6; Mon, 14 Sep 2026 16:54:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TSerfUiY"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CA9886869A for ; Mon, 14 Sep 2026 16:53:55 +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 93FEFC14; Mon, 14 Sep 2026 16:52:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789397535; bh=8QRyRtz82GmPeAaC1URStzYSFK12kl/HM5V6PUuspZY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TSerfUiYchLar6XOjGB+GlrVeAbTF5GBNRUtnq0B+PnngfyE48gjFz92eMyH1iZfP r2Ey3xROae9fedYaQcr/NFYJGYmbkCfYnCQuWWoHBlFSw/RCPdJWd9UouwOtqjOm58 Qn1hSycvhi8iaeZQFHh8l8nQEQ+mxoUifcVN3sjM= From: Daniel Scally Date: Mon, 14 Sep 2026 15:53:41 +0100 Subject: [PATCH v4 01/10] libipa: awb_grey: Correct minimum gain clamping MIME-Version: 1.0 Message-Id: <20260914-ipu3-libipa-rework-v4-1-ff8ee2d3dd24@ideasonboard.com> References: <20260914-ipu3-libipa-rework-v4-0-ff8ee2d3dd24@ideasonboard.com> In-Reply-To: <20260914-ipu3-libipa-rework-v4-0-ff8ee2d3dd24@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=1966; i=dan.scally@ideasonboard.com; h=from:subject:message-id; bh=8QRyRtz82GmPeAaC1URStzYSFK12kl/HM5V6PUuspZY=; b=owEBbQKS/ZANAwAKAchJV3psRXUyAcsmYgBqqAqAUxn3Oe5q20XbjTgmSK8dWZVxIAV3fY6fe nMldlcqQvWJAjMEAAEKAB0WIQQqyuwyDnZdb+mxmm/ISVd6bEV1MgUCaqgKgAAKCRDISVd6bEV1 MhKtEACysDO1cJrTrDJ6bfTU/Yg3nWkmvN9hnJzHlIEOPdEafX0CjyQWK/clWE+KBPA+ribc6Hg 7LRvVEKSv3YFQBuaQmPmYGBwhiLj4iSD5i1ICOl04UZ4FNoERbVUrtAkNBIcTItyNxaOK8OuoQL +rTdxVz2KtXB+fgdNpYyLeNr5r/52cZmbtFF93ZDicY5SSU0ciZRZZXEDz4Xa2ybcjn9ASjk44P HoHgAQ5YlTDJwkNbNpwvDX1e/no6NcffzcZ7dfwL8lWREUx5UnkxNIJFEJCdc4SLbBRtJrYucya BUj5IN+yLOnkof07lunjgHKfg3VEEdbjxEhlL7nCjLPdjJpK7BT9yuXrykbzk1Ejfutxl2mii1F jTiHiUvxZJpcKBVXPEyRlcMddKZIg1UWeU8oF73cEpkKQa2us+VQqd0NktJIB6uEImoTYcE31xM ert4/zklbzov9zaqioly/KU4RcmuiTboHs9dcMWqihYLJQo0hjBwtSejoun77pmIUn9gg5meN1b hoVKFUMFxrmLkZG7YVq/uOBgS2GruLFdzVcNkMJZXLqhoXAW6oJ5UmBST8/WvEaQjlliSsyMLWw ke7p8QUKQm9e0/1rjdlmUTtWmorOH+yjErmEsC0JtatMXYvpQGegI/VFzdJ052lXbpY0yws7J9H T2hX4eQmAm1BSzA== 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 Reviewed-by: Kieran Bingham --- 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; }