From patchwork Thu Dec 19 17:57:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22409 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 0671BC3272 for ; Thu, 19 Dec 2024 17:57:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AA1AD6847A; Thu, 19 Dec 2024 18:57:40 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Tfr8+kVi"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D587D68474 for ; Thu, 19 Dec 2024 18:57:36 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 02F20163; Thu, 19 Dec 2024 18:56:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631018; bh=gBKkFpfgJw6XNxBewuXZNebSbn7yqoT5Z9X/wlPa62k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tfr8+kVi6eWXyZT5yf61dmTOl/A+tH13qmmfWyAUDrKSEwSZ8KGqnxeM36/J6SWlV ET1ELxYynTFOfXBbcQCv1elL3uG8uSaEjFirLhOkqs5IdR7hCS0zFNRQ5GuLsClkFs ckTp1N+0P0XiQ5bMRSZ8I1tQeNS9KQmLql4wk0l0= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder , Kieran Bingham Subject: [PATCH v6 1/9] libcamera: controls: Update the ColourTemperature control to be writable Date: Thu, 19 Dec 2024 18:57:18 +0100 Message-ID: <20241219175729.293782-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" For manual control it is helpful to be able to specify a fixed colour temperature. It also provides an easy way to apply the temperature specific CCMs and colour gains that are contained in the tuning files. Document this and update the control dependencies. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Changes in v6: - Clarify interdependencies between ColourTemperature, ColourGains and ColourCorrectionMatrix Changes in v5: - Improve documentation --- src/libcamera/control_ids_core.yaml | 38 +++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index 073e0611d47c..1dfaee0c6327 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -298,7 +298,19 @@ controls: description: | Enable or disable the AWB. + When AWB is enabled, the algorithm estimates the colour temperature of + the scene and computes colour gains and the colour correction matrix + automatically. The computed colour temperature, gains and correction + matrix are reported in metadata. The corresponding controls are ignored + if set in a request. + + When AWB is disabled, the colour temperature, gains and correction + matrix are not updated automatically and can be set manually in + requests. + + \sa ColourCorrectionMatrix \sa ColourGains + \sa ColourTemperature # AwbMode needs further attention: # - Auto-generate max enum value. @@ -357,17 +369,34 @@ controls: order. ColourGains can only be applied in a Request when the AWB is disabled. + If ColourGains is set in a request but ColourTemperature is not, the + implementation shall calculate and set the ColourTemperature based on + the ColourGains. \sa AwbEnable + \sa ColourTemperature size: [2] - ColourTemperature: type: int32_t direction: out description: | - Report the estimate of the colour temperature for the frame, in kelvin. + ColourTemperature of the frame, in kelvin. + + ColourTemperature can only be applied in a Request when the AWB is + disabled. - The ColourTemperature control can only be returned in metadata. + If ColourTemperature is set in a request but ColourGains is not, the + implementation shall calculate and set the ColourGains based on the + given ColourTemperature. If ColourTemperature is set (either directly, + or indirectly by setting ColourGains) but ColourCorrectionMatrix is not, + the ColourCorrectionMatrix is updated based on the ColourTemperature. + + The ColourTemperature used to process the frame is reported in metadata. + + \sa AwbEnable + \sa ColourCorrectionMatrix + \sa ColourGains - Saturation: type: float @@ -429,6 +458,11 @@ controls: stored in conventional reading order in an array of 9 floating point values. + ColourCorrectionMatrix can only be applied in a Request when the AWB is + disabled. + + \sa AwbEnable + \sa ColourTemperature size: [3,3] - ScalerCrop: From patchwork Thu Dec 19 17:57:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22410 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 6A7C0C3272 for ; Thu, 19 Dec 2024 17:57:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ACCC66847E; Thu, 19 Dec 2024 18:57:41 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BRD8whS+"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B08E61899 for ; Thu, 19 Dec 2024 18:57:39 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 523346D6; Thu, 19 Dec 2024 18:57:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631020; bh=3kYmJGs6xN+tkPCw4zkGSo7C8b1y2iHIEh4PeJ1uMD8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BRD8whS+j5ycMDqsp1fbIHq4RHO+yD3XePsUb4Lz0Ry43znhfNZ+uM0sIYmHHK0mG j+qFVbH83+YXK/1vKjjRYvD8yttbCZOZhtU1herOxgKzTQ60wYrrAybWW/yEA6L/72 ev5r63lDDbkuglrm77wz/Q6ZXaPUuvfSDceDqxjM= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 2/9] ipa: rkisp1: awb: Load white balance gains from tuning file Date: Thu, 19 Dec 2024 18:57:19 +0100 Message-ID: <20241219175729.293782-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" For the implementation of a manual colour temperature setting, it is necessary to read predefined colour gains per colour temperature from the tuning file. Implement this in a backwards compatible way. If no gains are contained in the tuning file, loading just continues as before. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v6: - Rename gains_ to colourGainCurve_ - Rename gains to colourGains in tuning file Changes in v5: - Replace Interpolator with Interpolator --- src/ipa/rkisp1/algorithms/awb.cpp | 18 ++++++++++++++++++ src/ipa/rkisp1/algorithms/awb.h | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 4bb4f5b88375..e23f67a96edf 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -41,6 +41,24 @@ Awb::Awb() { } +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Awb::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) +{ + Interpolator> gainCurve; + int ret = gainCurve.readYaml(tuningData["colourGains"], "ct", "gains"); + if (ret < 0) + LOG(RkISP1Awb, Warning) + << "Failed to parse 'colourGains' " + << "parameter from tuning file; " + << "manual colour temperature will not work properly"; + else + colourGainCurve_ = gainCurve; + + return 0; +} + /** * \copydoc libcamera::ipa::Algorithm::configure */ diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h index 6ac3a5c3838b..e424804861a6 100644 --- a/src/ipa/rkisp1/algorithms/awb.h +++ b/src/ipa/rkisp1/algorithms/awb.h @@ -7,6 +7,11 @@ #pragma once +#include + +#include "libipa/interpolator.h" +#include "libipa/vector.h" + #include "algorithm.h" namespace libcamera { @@ -19,6 +24,7 @@ public: Awb(); ~Awb() = default; + int init(IPAContext &context, const YamlObject &tuningData) override; int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; void queueRequest(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, @@ -32,6 +38,7 @@ public: ControlList &metadata) override; private: + std::optional>> colourGainCurve_; bool rgbMode_; }; From patchwork Thu Dec 19 17:57:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22411 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 07F65C3272 for ; Thu, 19 Dec 2024 17:57:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 67D1E68486; Thu, 19 Dec 2024 18:57:47 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="AijzNkXE"; dkim-atps=neutral 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 21BBE68481 for ; Thu, 19 Dec 2024 18:57:42 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C63EAD8; Thu, 19 Dec 2024 18:57:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631023; bh=EFIMPL9bJiAOcv8nKEqT0wrUgTgwwYUg41VwflN086s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AijzNkXEhYSvLD4nd/hT7g9FCN3k5Y71lDan2a7NSu5iZoyhKatnFVpp1L06bZBBy Vh/QxoUo26u7BFh/OYdjAS+fMmwLIBIHO2EdMMTnNS/vYKFKUrgtNbeWu0YBZ+BPmY 9QjvhcZNYZKm9mzfiYmjS+mMnntmBJdWsKlDj1Pk= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder , Kieran Bingham Subject: [PATCH v6 3/9] ipa: rkisp1: awb: Implement ColourTemperature control Date: Thu, 19 Dec 2024 18:57:20 +0100 Message-ID: <20241219175729.293782-4-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" There are many use-cases (tuning-validation, working in static environments) where a manual ColourTemperature control is helpful. Implement that by interpolating and applying the white balance gains from the tuning file according to the requested colour temperature. If colour gains are provided on the same request, they take precedence. Store the colour temperature used for a given frame in the frame context and report that in metadata. Note that in the automatic case, the colour gains are still based on the gray world model and the CT curve from the tuning file get ignored. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Changes in v6: - Updated commit message - Moved retrieval of controls to the place where needed - Output the colour temperature applied to a frame in metadata --- src/ipa/rkisp1/algorithms/awb.cpp | 51 +++++++++++++++++++++++-------- src/ipa/rkisp1/ipa_context.h | 1 + 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index e23f67a96edf..cffaa06a22c1 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -33,6 +33,10 @@ namespace ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Awb) +constexpr int32_t kMinColourTemperature = 2500; +constexpr int32_t kMaxColourTemperature = 10000; +constexpr int32_t kDefaultColourTemperature = 5000; + /* Minimum mean value below which AWB can't operate. */ constexpr double kMeanMinThreshold = 2.0; @@ -44,8 +48,13 @@ Awb::Awb() /** * \copydoc libcamera::ipa::Algorithm::init */ -int Awb::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) +int Awb::init(IPAContext &context, const YamlObject &tuningData) { + auto &cmap = context.ctrlMap; + cmap[&controls::ColourTemperature] = ControlInfo(kMinColourTemperature, + kMaxColourTemperature, + kDefaultColourTemperature); + Interpolator> gainCurve; int ret = gainCurve.readYaml(tuningData["colourGains"], "ct", "gains"); if (ret < 0) @@ -68,6 +77,7 @@ int Awb::configure(IPAContext &context, context.activeState.awb.gains.manual = RGB{ 1.0 }; context.activeState.awb.gains.automatic = RGB{ 1.0 }; context.activeState.awb.autoEnabled = true; + context.activeState.awb.temperatureK = kDefaultColourTemperature; /* * Define the measurement window for AWB as a centered rectangle @@ -101,19 +111,37 @@ void Awb::queueRequest(IPAContext &context, << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; } + frameContext.awb.autoEnabled = awb.autoEnabled; + + if (awb.autoEnabled) + return; + const auto &colourGains = controls.get(controls::ColourGains); - if (colourGains && !awb.autoEnabled) { + const auto &colourTemperature = controls.get(controls::ColourTemperature); + bool update = false; + if (colourGains) { awb.gains.manual.r() = (*colourGains)[0]; awb.gains.manual.b() = (*colourGains)[1]; + /* + * \todo: Colour temperature reported in metadata is now + * incorrect, as we can't deduce the temperature from the gains. + * This will be fixed with the bayes AWB algorithm. + */ + update = true; + } else if (colourTemperature && colourGainCurve_) { + const auto &gains = colourGainCurve_->getInterpolated(*colourTemperature); + awb.gains.manual.r() = gains[0]; + awb.gains.manual.b() = gains[1]; + awb.temperatureK = *colourTemperature; + update = true; + } + if (update) LOG(RkISP1Awb, Debug) << "Set colour gains to " << awb.gains.manual; - } - frameContext.awb.autoEnabled = awb.autoEnabled; - - if (!awb.autoEnabled) - frameContext.awb.gains = awb.gains.manual; + frameContext.awb.gains = awb.gains.manual; + frameContext.awb.temperatureK = awb.temperatureK; } /** @@ -126,8 +154,10 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, * This is the latest time we can read the active state. This is the * most up-to-date automatic values we can read. */ - if (frameContext.awb.autoEnabled) + if (frameContext.awb.autoEnabled) { frameContext.awb.gains = context.activeState.awb.gains.automatic; + frameContext.awb.temperatureK = context.activeState.awb.temperatureK; + } auto gainConfig = params->block(); gainConfig.setEnabled(true); @@ -206,7 +236,7 @@ void Awb::process(IPAContext &context, static_cast(frameContext.awb.gains.r()), static_cast(frameContext.awb.gains.b()) }); - metadata.set(controls::ColourTemperature, activeState.awb.temperatureK); + metadata.set(controls::ColourTemperature, frameContext.awb.temperatureK); if (!stats || !(stats->meas_type & RKISP1_CIF_ISP_STAT_AWB)) { LOG(RkISP1Awb, Error) << "AWB data is missing in statistics"; @@ -281,9 +311,6 @@ void Awb::process(IPAContext &context, activeState.awb.temperatureK = estimateCCT(rgbMeans); - /* Metadata shall contain the up to date measurement */ - metadata.set(controls::ColourTemperature, activeState.awb.temperatureK); - /* * 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 diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index deb8c196f1b8..4b50015beee8 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -135,6 +135,7 @@ struct IPAFrameContext : public FrameContext { struct { RGB gains; bool autoEnabled; + unsigned int temperatureK; } awb; struct { From patchwork Thu Dec 19 17:57:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22412 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 678D2C3308 for ; Thu, 19 Dec 2024 17:57:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D8FC168484; Thu, 19 Dec 2024 18:57:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="D0iDC1NR"; dkim-atps=neutral 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 776D96846F for ; Thu, 19 Dec 2024 18:57:44 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A9E7C6D6; Thu, 19 Dec 2024 18:57:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631025; bh=LNBpWS0cIP3Bk0w0vDozqaE2k4jVG6q3WNt6pkNj5+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D0iDC1NRm+Vd+hROA/575uUQPiHnK5kdQUaZoz54z9yTW/c+AnTWbettpOYdSUhnF l4RRSmJA6G7cZwK9kzF5xWG/Vf1V8pHR4Sb8qP2AIgfZpCl/8DmpgNtO5CsIrpOvBe a9irrxam7VKpLF9hsBM8RoB4g0BUwqI3tUfi6YXo= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 4/9] libtuning: Use logging framework in ctt_awb.awb() Date: Thu, 19 Dec 2024 18:57:21 +0100 Message-ID: <20241219175729.293782-5-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" To be able to use the awb function copied from the Raspberry Pi tuning scripts in the libtuning code, we need to remove the Cam object. Use the logging framework to replace all accesses to Cam.log. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v6: - Move fix for Img.col to patch 6/8 Changes in v5: - Replace format() with f-strings --- utils/tuning/libtuning/ctt_awb.py | 48 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py index 63bb900045de..880094e9efe2 100644 --- a/utils/tuning/libtuning/ctt_awb.py +++ b/utils/tuning/libtuning/ctt_awb.py @@ -4,6 +4,8 @@ # # camera tuning tool for AWB +import logging + import matplotlib.pyplot as plt from bisect import bisect_left from scipy.optimize import fmin @@ -11,6 +13,7 @@ import numpy as np from .image import Image +logger = logging.getLogger(__name__) """ obtain piecewise linear approximation for colour curve @@ -39,7 +42,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): rb_raw = [] rbs_hat = [] for Img in imgs: - Cam.log += '\nProcessing '+Img.name + logger.info(f'Processing {Img.name}') """ get greyscale patches with alsc applied if alsc enabled. Note: if alsc is disabled then colour_cals will be set to None and the @@ -51,7 +54,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): """ r_g = np.mean(r_patchs/g_patchs) b_g = np.mean(b_patchs/g_patchs) - Cam.log += '\n r : {:.4f} b : {:.4f}'.format(r_g, b_g) + logger.info(f' r : {r_g:.4f} b : {b_g:.4f}') """ The curve tends to be better behaved in so-called hatspace. R, B, G represent the individual channels. The colour curve is plotted in @@ -74,12 +77,11 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): """ r_g_hat = r_g/(1+r_g+b_g) b_g_hat = b_g/(1+r_g+b_g) - Cam.log += '\n r_hat : {:.4f} b_hat : {:.4f}'.format(r_g_hat, b_g_hat) + logger.info(f' r_hat : {r_g_hat:.4f} b_hat : {b_g_hat:.4f}') rbs_hat.append((r_g_hat, b_g_hat, Img.col)) rb_raw.append((r_g, b_g)) - Cam.log += '\n' - Cam.log += '\nFinished processing images' + logger.info('Finished processing images') """ sort all lits simultaneously by r_hat """ @@ -95,7 +97,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): fit quadratic fit to r_g hat and b_g_hat """ a, b, c = np.polyfit(rbs_hat[0], rbs_hat[1], 2) - Cam.log += '\nFit quadratic curve in hatspace' + logger.info('Fit quadratic curve in hatspace') """ the algorithm now approximates the shortest distance from each point to the curve in dehatspace. Since the fit is done in hatspace, it is easier to @@ -151,14 +153,14 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): if (x+y) > (rr+bb): dist *= -1 dists.append(dist) - Cam.log += '\nFound closest point on fit line to each point in dehatspace' + logger.info('Found closest point on fit line to each point in dehatspace') """ calculate wiggle factors in awb. 10% added since this is an upper bound """ transverse_neg = - np.min(dists) * 1.1 transverse_pos = np.max(dists) * 1.1 - Cam.log += '\nTransverse pos : {:.5f}'.format(transverse_pos) - Cam.log += '\nTransverse neg : {:.5f}'.format(transverse_neg) + logger.info(f'Transverse pos : {transverse_pos:.5f}') + logger.info(f'Transverse neg : {transverse_neg:.5f}') """ set minimum transverse wiggles to 0.1 . Wiggle factors dictate how far off of the curve the algorithm searches. 0.1 @@ -167,10 +169,10 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): """ if transverse_pos < 0.01: transverse_pos = 0.01 - Cam.log += '\nForced transverse pos to 0.01' + logger.info('Forced transverse pos to 0.01') if transverse_neg < 0.01: transverse_neg = 0.01 - Cam.log += '\nForced transverse neg to 0.01' + logger.info('Forced transverse neg to 0.01') """ generate new b_hat values at each r_hat according to fit @@ -202,25 +204,25 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): i = len(c_fit) - 1 while i > 0: if c_fit[i] > c_fit[i-1]: - Cam.log += '\nColour temperature increase found\n' - Cam.log += '{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1]) - Cam.log += '{} K at r = {}'.format(c_fit[i], r_fit[i]) + logger.info('Colour temperature increase found') + logger.info(f'{c_fit[i - 1]} K at r = {r_fit[i - 1]} to ') + logger.info(f'{c_fit[i]} K at r = {r_fit[i]}') """ if colour temperature increases then discard point furthest from the transformed fit (dehatspace) """ error_1 = abs(dists[i-1]) error_2 = abs(dists[i]) - Cam.log += '\nDistances from fit:\n' - Cam.log += '{} K : {:.5f} , '.format(c_fit[i], error_1) - Cam.log += '{} K : {:.5f}'.format(c_fit[i-1], error_2) + logger.info('Distances from fit:') + logger.info(f'{c_fit[i]} K : {error_1:.5f}') + logger.info(f'{c_fit[i - 1]} K : {error_2:.5f}') """ find bad index note that in python false = 0 and true = 1 """ bad = i - (error_1 < error_2) - Cam.log += '\nPoint at {} K deleted as '.format(c_fit[bad]) - Cam.log += 'it is furthest from fit' + logger.info(f'Point at {c_fit[bad]} K deleted as ') + logger.info('it is furthest from fit') """ delete bad point """ @@ -239,12 +241,12 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot): return formatted ct curve, ordered by increasing colour temperature """ ct_curve = list(np.array(list(zip(b_fit, r_fit, c_fit))).flatten())[::-1] - Cam.log += '\nFinal CT curve:' + logger.info('Final CT curve:') for i in range(len(ct_curve)//3): j = 3*i - Cam.log += '\n ct: {} '.format(ct_curve[j]) - Cam.log += ' r: {} '.format(ct_curve[j+1]) - Cam.log += ' b: {} '.format(ct_curve[j+2]) + logger.info(f' ct: {ct_curve[j]} ') + logger.info(f' r: {ct_curve[j + 1]} ') + logger.info(f' b: {ct_curve[j + 2]} ') """ plotting code for debug From patchwork Thu Dec 19 17:57:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22413 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 67DB5C3272 for ; Thu, 19 Dec 2024 17:57:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CCB206848A; Thu, 19 Dec 2024 18:57:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BCgT1Yq0"; dkim-atps=neutral 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 3F73E68481 for ; Thu, 19 Dec 2024 18:57:47 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 75B28163; Thu, 19 Dec 2024 18:57:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631028; bh=5H8nnBn4EDC5HJdWD5yX/HvXnw066g2IBJqGpnHHzqU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BCgT1Yq0QUfB0EAxcJnWOydVcQDnzFzEnwJHLGyWlHa7+TNQpARGsWjKvFxaGZiyQ T88U4vYCkBMrS6GiGD5wz6+oK0FxF/MkN03QkrPX1KhYj+kWQeDBT9FTDW886Q4d3D zGAYOi6USDJI2UGzLoFwL/JamOQvjHU3Hv5lMB1k= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 5/9] libtuning: Remove the Cam object from ctt_awb.awb() Date: Thu, 19 Dec 2024 18:57:22 +0100 Message-ID: <20241219175729.293782-6-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" Replace the Cam object with a list parameter to be able to call the ctt_awb.awb() function from libtuning code. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- utils/tuning/libtuning/ctt_awb.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py index 880094e9efe2..b996daba0213 100644 --- a/utils/tuning/libtuning/ctt_awb.py +++ b/utils/tuning/libtuning/ctt_awb.py @@ -18,8 +18,7 @@ logger = logging.getLogger(__name__) """ obtain piecewise linear approximation for colour curve """ -def awb(Cam, cal_cr_list, cal_cb_list, plot): - imgs = Cam.imgs +def awb(imgs, cal_cr_list, cal_cb_list, plot): """ condense alsc calibration tables into one dictionary """ From patchwork Thu Dec 19 17:57:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22414 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 2202CC3309 for ; Thu, 19 Dec 2024 17:57:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6D9CC6848C; Thu, 19 Dec 2024 18:57:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WBBXzON8"; dkim-atps=neutral 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 BB6076846F for ; Thu, 19 Dec 2024 18:57:49 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EA7F36D6; Thu, 19 Dec 2024 18:57:10 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631031; bh=EnI4zDdJeJn5HH+Gq2nY3+8buAk7TKwwaH8oVRx13tQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WBBXzON8gv4W/Tsd+awNLzHD1XanpRfJ2INxSnMPDb5cP0turdm3HHyujudtCMO+l +HRalci4BNbdDBW8pM8hzCSeT+mY9Lsp6mTLaFQvtGG/zciqr4RIZnTTkDI1u2oGsK CL1o9L/ueqNtJALlSJLVo4fzH8qrwAQecPqrwjeM= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 6/9] libtuning: Fix access to color member in ctt_awb.awb() Date: Thu, 19 Dec 2024 18:57:23 +0100 Message-ID: <20241219175729.293782-7-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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 color temperature member of the image object was named "col" in the past. Now it is named "color" (which is still not very expressive). There are still a few unspotted accesses to the col member. Fix them to access the color member. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- utils/tuning/libtuning/ctt_awb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py index b996daba0213..240f37e644bb 100644 --- a/utils/tuning/libtuning/ctt_awb.py +++ b/utils/tuning/libtuning/ctt_awb.py @@ -77,7 +77,7 @@ def awb(imgs, cal_cr_list, cal_cb_list, plot): r_g_hat = r_g/(1+r_g+b_g) b_g_hat = b_g/(1+r_g+b_g) logger.info(f' r_hat : {r_g_hat:.4f} b_hat : {b_g_hat:.4f}') - rbs_hat.append((r_g_hat, b_g_hat, Img.col)) + rbs_hat.append((r_g_hat, b_g_hat, Img.color)) rb_raw.append((r_g, b_g)) logger.info('Finished processing images') @@ -305,7 +305,7 @@ def get_alsc_patches(Img, colour_cals, grey=True): patches = Img.patches if grey: cen_coords = Img.cen_coords[3::4] - col = Img.col + col = Img.color r_patchs = patches[0][3::4] - Img.blacklevel_16 b_patchs = patches[3][3::4] - Img.blacklevel_16 """ From patchwork Thu Dec 19 17:57:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22415 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 51A26C3308 for ; Thu, 19 Dec 2024 17:57:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F187F68489; Thu, 19 Dec 2024 18:57:56 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kjvx/ZVi"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3DDCB68480 for ; Thu, 19 Dec 2024 18:57:53 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 71C076D6; Thu, 19 Dec 2024 18:57:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631034; bh=E3YVIewT5sPLsLIs5Ro7gZMwWTnCo66a55NNviKQzdM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kjvx/ZVio41xT7VywHVYTa5i4jtF02Z6/qiffZ7o62IY0jdgJMbVy4adXkUdamTC2 gwj80aEvfWZMwHjBuJjkaZPDZ7b1XT9+2wDT5Zbf0m3tId1ddA3dAQ5JXDxRTiNgf9 Mlm570dxbGDbl64AR3dfQ764sF5ty8WSQpUpwwVI= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 7/9] libtuning: Add initial AWB module Date: Thu, 19 Dec 2024 18:57:24 +0100 Message-ID: <20241219175729.293782-8-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" This AWB module uses the awb function from Raspberry Pi to calculate the needed white balance gains per colour temperature. It stores these gains in the tuning file. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- .../tuning/libtuning/modules/awb/__init__.py | 6 ++++ utils/tuning/libtuning/modules/awb/awb.py | 36 +++++++++++++++++++ utils/tuning/libtuning/modules/awb/rkisp1.py | 27 ++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 utils/tuning/libtuning/modules/awb/__init__.py create mode 100644 utils/tuning/libtuning/modules/awb/awb.py create mode 100644 utils/tuning/libtuning/modules/awb/rkisp1.py diff --git a/utils/tuning/libtuning/modules/awb/__init__.py b/utils/tuning/libtuning/modules/awb/__init__.py new file mode 100644 index 000000000000..2d67f10cfc4f --- /dev/null +++ b/utils/tuning/libtuning/modules/awb/__init__.py @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Ideas On Board + +from libtuning.modules.awb.awb import AWB +from libtuning.modules.awb.rkisp1 import AWBRkISP1 diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py new file mode 100644 index 000000000000..c154cf3b8609 --- /dev/null +++ b/utils/tuning/libtuning/modules/awb/awb.py @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Ideas On Board + +import logging + +from ..module import Module + +from libtuning.ctt_awb import awb +import numpy as np + +logger = logging.getLogger(__name__) + + +class AWB(Module): + type = 'awb' + hr_name = 'AWB (Base)' + out_name = 'GenericAWB' + + def __init__(self, *, debug: list): + super().__init__() + + self.debug = debug + + def do_calculation(self, images): + logger.info('Starting AWB calculation') + + imgs = [img for img in images if img.macbeth is not None] + + gains, _, _ = awb(imgs, None, None, False) + gains = np.reshape(gains, (-1, 3)) + + return [{ + 'ct': int(v[0]), + 'gains': [float(1.0 / v[1]), float(1.0 / v[2])] + } for v in gains] diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py new file mode 100644 index 000000000000..0c95843b83d3 --- /dev/null +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Ideas On Board +# +# AWB module for tuning rkisp1 + +from .awb import AWB + +import libtuning as lt + + +class AWBRkISP1(AWB): + hr_name = 'AWB (RkISP1)' + out_name = 'Awb' + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def validate_config(self, config: dict) -> bool: + return True + + def process(self, config: dict, images: list, outputs: dict) -> dict: + output = {} + + output['colourGains'] = self.do_calculation(images) + + return output From patchwork Thu Dec 19 17:57:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22416 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 1624BC3272 for ; Thu, 19 Dec 2024 17:58:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 50C0768491; Thu, 19 Dec 2024 18:57:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sRsXFU5a"; dkim-atps=neutral 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 87F496848E for ; Thu, 19 Dec 2024 18:57:55 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C0600163; Thu, 19 Dec 2024 18:57:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631036; bh=GIDf4SFqGRW15SOHRkYnSYz+H836dVqkFf16SLOo0sE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sRsXFU5astj+lRPYX8LmXrePEkD/nMAhM8LyQAR7MNVkKA2p48xveyrSPRZh0IXzd ampNnx86jvEwgv4rsW4ffrkrJtVqDBPgd2Bw1ofWC3QKbQQGSkgLqdwn7rGF3QdwUX oL3PMci9mrAjHZa33FrLZF9Mv65W4UPqt3PfS+q8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v6 8/9] utils: tuning: rkisp1: Replace static AWB with new AWB module Date: Thu, 19 Dec 2024 18:57:25 +0100 Message-ID: <20241219175729.293782-9-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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 rkisp1 tuner used a static module to insert the AWB algorithm into the tuning file. Replace that with the new AWB module. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- utils/tuning/rkisp1.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/tuning/rkisp1.py b/utils/tuning/rkisp1.py index f5c42a61d15e..9f40fd8bd63b 100755 --- a/utils/tuning/rkisp1.py +++ b/utils/tuning/rkisp1.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # # Copyright (C) 2022, Paul Elder +# Copyright (C) 2024, Ideas On Board # # Tuning script for rkisp1 @@ -14,13 +15,14 @@ from libtuning.parsers import YamlParser from libtuning.generators import YamlOutput from libtuning.modules.lsc import LSCRkISP1 from libtuning.modules.agc import AGCRkISP1 +from libtuning.modules.awb import AWBRkISP1 from libtuning.modules.ccm import CCMRkISP1 from libtuning.modules.static import StaticModule coloredlogs.install(level=logging.INFO, fmt='%(name)s %(levelname)s %(message)s') agc = AGCRkISP1(debug=[lt.Debug.Plot]) -awb = StaticModule('Awb') +awb = AWBRkISP1(debug=[lt.Debug.Plot]) blc = StaticModule('BlackLevelCorrection') ccm = CCMRkISP1(debug=[lt.Debug.Plot]) color_processing = StaticModule('ColorProcessing') From patchwork Thu Dec 19 17:57:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22417 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 441C9C3309 for ; Thu, 19 Dec 2024 17:58:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CC2EC68490; Thu, 19 Dec 2024 18:58:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="RDY+9WTA"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3FE2A68484 for ; Thu, 19 Dec 2024 18:57:58 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:783:85f9:c998:cb11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 61A7D163; Thu, 19 Dec 2024 18:57:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734631039; bh=K9lhLOINx1KLtkNJJh12tsv1fR7W7J2SUQfX43GMa6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RDY+9WTAuWDuBPuKYEiK5YySkFDda1KtX7Z7Wfqd/05iPGn6DMmnvQco44r5lE+L6 q/88uqa0w4tU8PVP7uFCExrCeW+QTOAIsrcPwKUgbB2ZBxFNbXJcFVD52GwuZeEzbV IQOWACmp1S1JV6bCEhnWKYUDWmplY1XT334IprLg= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: David Plowman , Naushir Patuck , Kieran Bingham , Stefan Klug Subject: [PATCH v6 9/9] ipa: rpi: awb: Make it possible to set the colour temperature directly Date: Thu, 19 Dec 2024 18:57:26 +0100 Message-ID: <20241219175729.293782-10-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241219175729.293782-1-stefan.klug@ideasonboard.com> References: <20241219175729.293782-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" From: David Plowman ColourTemperature is now exported as a writable control so that applications can set it directly. The AWB algorithm class now requires a method to be provided to perform this operation. The method should clamp the passed value to the calibrated range known to the algorithm. The default range is set very wide to cover all conceivable future AWB calibrations. It will always be clamped before use. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck Reviewed-by: Kieran Bingham Signed-off-by: Stefan Klug Tested-by: Stefan Klug --- Changes in v6: - Added this commit from https://patchwork.libcamera.org/patch/19232/ --- src/ipa/rpi/common/ipa_base.cpp | 20 ++++++++++++++++++++ src/ipa/rpi/controller/awb_algorithm.h | 1 + src/ipa/rpi/controller/rpi/awb.cpp | 18 ++++++++++++++++++ src/ipa/rpi/controller/rpi/awb.h | 1 + 4 files changed, 40 insertions(+) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 45e2a1d7a6eb..0c8aee699155 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -81,6 +81,7 @@ const ControlInfoMap::Map ipaColourControls{ { &controls::AwbEnable, ControlInfo(false, true) }, { &controls::AwbMode, ControlInfo(controls::AwbModeValues) }, { &controls::ColourGains, ControlInfo(0.0f, 32.0f) }, + { &controls::ColourTemperature, ControlInfo(100, 100000) }, { &controls::Saturation, ControlInfo(0.0f, 32.0f, 1.0f) }, }; @@ -1011,6 +1012,25 @@ void IpaBase::applyControls(const ControlList &controls) break; } + case controls::COLOUR_TEMPERATURE: { + /* Silently ignore this control for a mono sensor. */ + if (monoSensor_) + break; + + auto temperatureK = ctrl.second.get(); + RPiController::AwbAlgorithm *awb = dynamic_cast( + controller_.getAlgorithm("awb")); + if (!awb) { + LOG(IPARPI, Warning) + << "Could not set COLOUR_TEMPERATURE - no AWB algorithm"; + break; + } + + awb->setColourTemperature(temperatureK); + /* This metadata will get reported back automatically. */ + break; + } + case controls::BRIGHTNESS: { RPiController::ContrastAlgorithm *contrast = dynamic_cast( controller_.getAlgorithm("contrast")); diff --git a/src/ipa/rpi/controller/awb_algorithm.h b/src/ipa/rpi/controller/awb_algorithm.h index 1779b0500a04..d941ed4e3476 100644 --- a/src/ipa/rpi/controller/awb_algorithm.h +++ b/src/ipa/rpi/controller/awb_algorithm.h @@ -19,6 +19,7 @@ public: virtual void initialValues(double &gainR, double &gainB) = 0; virtual void setMode(std::string const &modeName) = 0; virtual void setManualGains(double manualR, double manualB) = 0; + virtual void setColourTemperature(double temperatureK) = 0; virtual void enableAuto() = 0; virtual void disableAuto() = 0; }; diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp index c277a1764112..8479ae40951d 100644 --- a/src/ipa/rpi/controller/rpi/awb.cpp +++ b/src/ipa/rpi/controller/rpi/awb.cpp @@ -293,6 +293,24 @@ void Awb::setManualGains(double manualR, double manualB) } } +void Awb::setColourTemperature(double temperatureK) +{ + if (!config_.bayes) { + LOG(RPiAwb, Warning) << "AWB uncalibrated - cannot set colour temperature"; + return; + } + + temperatureK = config_.ctR.domain().clamp(temperatureK); + manualR_ = 1 / config_.ctR.eval(temperatureK); + manualB_ = 1 / config_.ctB.eval(temperatureK); + + syncResults_.temperatureK = temperatureK; + syncResults_.gainR = manualR_; + syncResults_.gainG = 1.0; + syncResults_.gainB = manualB_; + prevSyncResults_ = syncResults_; +} + void Awb::switchMode([[maybe_unused]] CameraMode const &cameraMode, Metadata *metadata) { diff --git a/src/ipa/rpi/controller/rpi/awb.h b/src/ipa/rpi/controller/rpi/awb.h index 5d628b47c8a6..86640f8f8e21 100644 --- a/src/ipa/rpi/controller/rpi/awb.h +++ b/src/ipa/rpi/controller/rpi/awb.h @@ -105,6 +105,7 @@ public: void initialValues(double &gainR, double &gainB) override; void setMode(std::string const &name) override; void setManualGains(double manualR, double manualB) override; + void setColourTemperature(double temperatureK) override; void enableAuto() override; void disableAuto() override; void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;