From patchwork Fri Dec 6 14:52: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: 22218 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 A2AC1BF415 for ; Fri, 6 Dec 2024 14:52:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 680666615F; Fri, 6 Dec 2024 15:52:53 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="g0GFToL6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6CF0A6614C for ; Fri, 6 Dec 2024 15:52:50 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CBFAB641; Fri, 6 Dec 2024 15:52:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496740; bh=OD6S88E9NiwAvWE9IB9CFpL4roYQ0zm9YER3Y/+TXgM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g0GFToL6UZd87UCIuSneaxSXEHU8wgU4BpACscwPkKjodUQtodEhFT4wsaAGsG1Mg Cpd5MPSYE0s2ZdXvz/rzhOg0gHh+rlbE3t5glWVIxrtp7bIXaOh1UgDDhpVaCL8Ytm EQkeNtsf/B6UwtUdhPCPvNAfueLIXKA5JOmbO9dc= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder Subject: [PATCH v5 1/8] libcamera: controls: Update the ColourTemperature control to be writable Date: Fri, 6 Dec 2024 15:52:21 +0100 Message-ID: <20241206145242.827886-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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 --- Changes in v5: - Improve documentation --- src/libcamera/control_ids_core.yaml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index d45cf8e56187..3795f7169911 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -283,7 +283,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 temperate, 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. @@ -341,14 +353,25 @@ controls: ColourGains can only be applied in a Request when the AWB is disabled. \sa AwbEnable + \sa ColourTemperature size: [2] - ColourTemperature: type: int32_t description: | - Report the estimate of the colour temperature for the frame, in kelvin. + Report the current estimate of the colour temperature, in kelvin, for + this frame. An implementation may allow this control to be set when AWB + is disabled. In that case ColourGains and the ColourCorrectionMatrix get + set accordingly. If ColourGains and ColourTemperature are specified at + the same time, ColourGains takes precedence. The same applies to + ColourCorrectionMatrix. + + The metadata will only report measured colour temperature values when + available, even if set manually. - The ColourTemperature control can only be returned in metadata. + \sa AwbEnable + \sa ColourCorrectionMatrix + \sa ColourGains - Saturation: type: float @@ -405,6 +428,8 @@ controls: stored in conventional reading order in an array of 9 floating point values. + \sa AwbEnable + \sa ColourTemperature size: [3,3] - ScalerCrop: From patchwork Fri Dec 6 14:52: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: 22219 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 36355BF415 for ; Fri, 6 Dec 2024 14:52:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D9D1866179; Fri, 6 Dec 2024 15:52:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="v9ab/kEx"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2EA9B6614C for ; Fri, 6 Dec 2024 15:52:53 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ADC85641; Fri, 6 Dec 2024 15:52:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496743; bh=ZIZFnD6KTrmdNF7FrJ8iqLM05F3FdPGrBhUxffIHhJU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v9ab/kEx6FXx/GqJmVXW+W6Yhpl7IOo3xSIP5sfC0V53h96i2heFKiIuhx4LCVPf5 iAdoXFLyZEqSTKGH7u2rZQTzBymgdJyJxroT6NAXOz/NF54ATlfjr2gnre//8ljVut VOxwfaP1bc3Xi1bidGyxT5PBg7prnaipTjujF27s= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v5 2/8] ipa: rkisp1: awb: Load white balance gains from tuning file Date: Fri, 6 Dec 2024 15:52:22 +0100 Message-ID: <20241206145242.827886-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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 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..23a81e75d3d3 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> gains; + int ret = gains.readYaml(tuningData["gains"], "ct", "gains"); + if (ret < 0) + LOG(RkISP1Awb, Warning) + << "Failed to parse 'gains' " + << "parameter from tuning file; " + << "manual colour temperature will not work properly"; + else + gains_ = gains; + + 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..a7e0537c66d9 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>> gains_; bool rgbMode_; }; From patchwork Fri Dec 6 14:52: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: 22220 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 DD643BF415 for ; Fri, 6 Dec 2024 14:52:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 972A96615F; Fri, 6 Dec 2024 15:52:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="NRMNoJlS"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 22ADA6615F for ; Fri, 6 Dec 2024 15:52:56 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4AFCB641; Fri, 6 Dec 2024 15:52:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496746; bh=2FLxC8TgZOLDJJOO/13xn0N0PRQZ0JY/NUSsuDaKXW0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NRMNoJlSEPtzVCDyl07d1hs2CTtIVuyUQypaReG3ja6yaTwBAhO/24xWNNsBLF/Rb a1U0PR7ViiGvL3sF4eFUyXvzarbxDnjkfZzcgJtWjKiNjQLsfK556GKXdSug1i75yY 1e0nickqVFOaLISVJQ7SWJGosfsQHYMWof11mhIY= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Paul Elder Subject: [PATCH v5 3/8] ipa: rkisp1: awb: Implement ColourTemperature control Date: Fri, 6 Dec 2024 15:52:23 +0100 Message-ID: <20241206145242.827886-4-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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. As the colour temperature reported in the metadata is always based on the measurements, we don't have to touch that. Note that in the automatic case, the colour gains are still based on the gray world model and the ones from the tuning file get ignored. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham --- src/ipa/rkisp1/algorithms/awb.cpp | 35 ++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 23a81e75d3d3..41f260e7089c 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 = 6500; + /* 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> gains; int ret = gains.readYaml(tuningData["gains"], "ct", "gains"); if (ret < 0) @@ -101,19 +110,31 @@ void Awb::queueRequest(IPAContext &context, << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; } + frameContext.awb.autoEnabled = awb.autoEnabled; + const auto &colourGains = controls.get(controls::ColourGains); - if (colourGains && !awb.autoEnabled) { + const auto &colourTemperature = controls.get(controls::ColourTemperature); + + if (awb.autoEnabled) + return; + + bool update = false; + if (colourGains) { awb.gains.manual.r() = (*colourGains)[0]; awb.gains.manual.b() = (*colourGains)[1]; + update = true; + } else if (colourTemperature && gains_) { + auto gains = gains_->getInterpolated(*colourTemperature); + awb.gains.manual.r() = gains[0]; + awb.gains.manual.b() = gains[1]; + 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; } /** From patchwork Fri Dec 6 14:52: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: 22221 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 AB769BF415 for ; Fri, 6 Dec 2024 14:53:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6568767E16; Fri, 6 Dec 2024 15:53:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="QJinJVdB"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BDBE167E16 for ; Fri, 6 Dec 2024 15:52:58 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 497F1641; Fri, 6 Dec 2024 15:52:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496749; bh=bFF22ma/oewaUTizd+snVEKMnX5jHL+VVzQ0qRmlag4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QJinJVdBIOaznMJ7VktmjKLUdVhX+aIZV0pXNaqHkIh0KL6cOWJAoFx7SRRlV98jJ guytobV7Lk0KUNQCD6c3PcPqdaNACn8YvMBgBpWproEt3pLSWtoE6wgIx8DUxikCZN zonxTASl2L0O5J3HUGf2KjMW69vKGrl7JrBIzVeM= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder Subject: [PATCH v5 4/8] libtuning: Use logging framework in ctt_awb.awb() Date: Fri, 6 Dec 2024 15:52:24 +0100 Message-ID: <20241206145242.827886-5-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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 v5: - Replace format() with f-strings --- utils/tuning/libtuning/ctt_awb.py | 50 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py index abf22321a0ea..899f204da8cf 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) - rbs_hat.append((r_g_hat, b_g_hat, Img.col)) + 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.color)) 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 Fri Dec 6 14:52: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: 22222 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 7C300BF415 for ; Fri, 6 Dec 2024 14:53:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2F77966179; Fri, 6 Dec 2024 15:53:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DE6/GfC9"; 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 ED5536615F for ; Fri, 6 Dec 2024 15:53:01 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7443474C; Fri, 6 Dec 2024 15:52:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496752; bh=zEa0giMAor74Ze70kLrhcVCVb36GahiNhnD5J4fildc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DE6/GfC9fdge2GscmyIWaUExM31LkdiEYU9WPGBQLHSPkw51GRK+OdgE3Xr1e1FXB g61ChOwNxER5ekSGjqNKmCy9y0P9+KRtnNx0uASC7HgfwNTvpXTE8Fk1WXPjSEn2u2 ghcX/Q7D0uBllAuWzSjsTvAZvZEkN1UixbFMlrNg= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder Subject: [PATCH v5 5/8] libtuning: Remove the Cam object from ctt_awb.awb() Date: Fri, 6 Dec 2024 15:52:25 +0100 Message-ID: <20241206145242.827886-6-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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 899f204da8cf..5494bdb5c103 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 Fri Dec 6 14:52: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: 22223 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 09147BF415 for ; Fri, 6 Dec 2024 14:53:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B1FB566168; Fri, 6 Dec 2024 15:53:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Uy1XB2p3"; 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 F36B26615F for ; Fri, 6 Dec 2024 15:53:04 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C2FA74C; Fri, 6 Dec 2024 15:52:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496755; bh=qOc2oaCSQuCoeb1Ao+YhvcFWgrNJ4l4ojOBWyGN99fI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Uy1XB2p3nYEF06tS00JNUWIDy/gpCQUJv4JLuEfQmjBqBLaHPrOoOhm8BIm3AEbNR C13QPIP059gfAxafQQwCy7XB2sZoIb1otGP42p/FBCdqMkfrsSmjpsTMO/lDpPh3ZR OKNeptzQIrVjX7wuJAtRzZ+ZPkTMoxZ9bZloVhpY= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder Subject: [PATCH v5 6/8] libtuning: Fix access to color member in ctt_awb.awb() Date: Fri, 6 Dec 2024 15:52:26 +0100 Message-ID: <20241206145242.827886-7-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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" Fix the access to the color temperature member of the Img object. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- utils/tuning/libtuning/ctt_awb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py index 5494bdb5c103..117612f2582a 100644 --- a/utils/tuning/libtuning/ctt_awb.py +++ b/utils/tuning/libtuning/ctt_awb.py @@ -304,7 +304,7 @@ def get_alsc_patches(Img, colour_cals, grey=True): """ if grey: cen_coords = Img.cen_coords[3::4] - col = Img.col + col = Img.color patches = [np.array(Img.patches[i]) for i in Img.order] r_patchs = patches[0][3::4] - Img.blacklevel_16 b_patchs = patches[3][3::4] - Img.blacklevel_16 From patchwork Fri Dec 6 14:52:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22224 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 C1EACBF415 for ; Fri, 6 Dec 2024 14:53:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 76E9F67E21; Fri, 6 Dec 2024 15:53:08 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Me5HeoLj"; 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 3583E66179 for ; Fri, 6 Dec 2024 15:53:07 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B7C92641; Fri, 6 Dec 2024 15:52:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496757; bh=oG9BRNds5/JmYJBTC/Vd4tha/uR9fHvsfr7GftDGUWM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Me5HeoLjircsGSNxTwOfKbndmMpNXbCGuyxJVce/sqdx1csxXCVK2SFs92bK7GhCT VhahTZdwyPzU6U3D16uJvFgJlfacyv71agI72lCrh/Netlg3HnwHT25Yf0iMzq9frh 4dVx3uhbJpPZb2PF7F3g/FqHOzfe8HsOi25eGHRM= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v5 7/8] libtuning: Add initial AWB module Date: Fri, 6 Dec 2024 15:52:27 +0100 Message-ID: <20241206145242.827886-8-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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..e3ddeb50c9a1 --- /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['gains'] = self.do_calculation(images) + + return output From patchwork Fri Dec 6 14:52:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22225 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 7DAD3BF415 for ; Fri, 6 Dec 2024 14:53:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3494667E24; Fri, 6 Dec 2024 15:53:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="YbsGNkn8"; 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 B2B5867E1E for ; Fri, 6 Dec 2024 15:53:09 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4004B74C; Fri, 6 Dec 2024 15:52:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733496760; bh=GIDf4SFqGRW15SOHRkYnSYz+H836dVqkFf16SLOo0sE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YbsGNkn8YU3CT9FpUvh11EPlx1hw26ChLxjek5N/9OnHnhtNsEZmuoWBl+M0NKayq WK+woFuO3elsfavxrJAU5YrmBQYuht+Df3zOK+AY4lFVqPNIkVaTGUG13U0VPGeqT7 nugno5HunXR3XI7oxFq5YWbW4nBanA0fJtkakE3s= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder , Laurent Pinchart Subject: [PATCH v5 8/8] utils: tuning: rkisp1: Replace static AWB with new AWB module Date: Fri, 6 Dec 2024 15:52:28 +0100 Message-ID: <20241206145242.827886-9-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241206145242.827886-1-stefan.klug@ideasonboard.com> References: <20241206145242.827886-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')