From patchwork Fri Jul 5 14:41:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 20605 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 E2878BEFBE for ; Fri, 5 Jul 2024 14:42:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 45DE963370; Fri, 5 Jul 2024 16:42:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nIq8B9QU"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 85CBD6336B for ; Fri, 5 Jul 2024 16:42:54 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:60b6:33a3:3a20:6030]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F3B644CC; Fri, 5 Jul 2024 16:42:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1720190545; bh=GBZkLqhbZW/iyGhPYbDSNGTRx1tvnXKuoymrc6jp+mE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nIq8B9QUcHFosr73azOtE/0iIFk/67tuNYOUiSlNLRLEpA9JsJoRviy7Bx3nqGwd2 gRrPJls6L4R7q40smmakRF96V5MoOKzXIISuJYEuvY0IRABKXbb+Gq+G5mWhAld8zf 1PWCOCqDn7SY5kR7j9/oLXRqVzb8cG+9HdsaRVds= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Stefan Klug , Laurent Pinchart Subject: [PATCH v4 16/23] libtuning: modules: Add initial CCM module Date: Fri, 5 Jul 2024 16:41:52 +0200 Message-ID: <20240705144209.418906-17-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240705144209.418906-1-stefan.klug@ideasonboard.com> References: <20240705144209.418906-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: Paul Elder Implement a minimal ccm calibration module. For now it doesn't take the results from lsc into account and supports rkisp1 only. Signed-off-by: Paul Elder Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Scally --- .../tuning/libtuning/modules/ccm/__init__.py | 6 +++ utils/tuning/libtuning/modules/ccm/ccm.py | 41 +++++++++++++++++++ utils/tuning/libtuning/modules/ccm/rkisp1.py | 28 +++++++++++++ utils/tuning/rkisp1.py | 4 +- 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 utils/tuning/libtuning/modules/ccm/__init__.py create mode 100644 utils/tuning/libtuning/modules/ccm/ccm.py create mode 100644 utils/tuning/libtuning/modules/ccm/rkisp1.py diff --git a/utils/tuning/libtuning/modules/ccm/__init__.py b/utils/tuning/libtuning/modules/ccm/__init__.py new file mode 100644 index 000000000000..322602afe63b --- /dev/null +++ b/utils/tuning/libtuning/modules/ccm/__init__.py @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Paul Elder + +from libtuning.modules.ccm.ccm import CCM +from libtuning.modules.ccm.rkisp1 import CCMRkISP1 diff --git a/utils/tuning/libtuning/modules/ccm/ccm.py b/utils/tuning/libtuning/modules/ccm/ccm.py new file mode 100644 index 000000000000..18702f8db887 --- /dev/null +++ b/utils/tuning/libtuning/modules/ccm/ccm.py @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Paul Elder +# Copyright (C) 2024, Ideas on Board +# +# Base Ccm tuning module + +from ..module import Module + +from libtuning.ctt_ccm import ccm +import logging + +logger = logging.getLogger(__name__) + + +class CCM(Module): + type = 'ccm' + hr_name = 'CCM (Base)' + out_name = 'GenericCCM' + + def __init__(self, debug: list): + super().__init__() + + self.debug = debug + + def do_calibration(self, images): + logger.info('Starting CCM calibration') + + imgs = [img for img in images if img.macbeth is not None] + + # todo: Take LSC calibration results into account. + cal_cr_list = None + cal_cb_list = None + + try: + ccms = ccm(imgs, cal_cr_list, cal_cb_list) + except ArithmeticError: + logger.error('CCM calibration failed') + return None + + return ccms diff --git a/utils/tuning/libtuning/modules/ccm/rkisp1.py b/utils/tuning/libtuning/modules/ccm/rkisp1.py new file mode 100644 index 000000000000..be0252d9c1c4 --- /dev/null +++ b/utils/tuning/libtuning/modules/ccm/rkisp1.py @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024, Paul Elder +# Copyright (C) 2024, Ideas on Board +# +# Ccm module for tuning rkisp1 + +from .ccm import CCM + + +class CCMRkISP1(CCM): + hr_name = 'Crosstalk Correction (RkISP1)' + out_name = 'Ccm' + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + # We don't need anything from the config file. + def validate_config(self, config: dict) -> bool: + return True + + def process(self, config: dict, images: list, outputs: dict) -> dict: + output = {} + + ccms = self.do_calibration(images) + output['ccms'] = ccms + + return output diff --git a/utils/tuning/rkisp1.py b/utils/tuning/rkisp1.py index 2606e07a93f7..fae35783c656 100755 --- a/utils/tuning/rkisp1.py +++ b/utils/tuning/rkisp1.py @@ -14,6 +14,7 @@ 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.ccm import CCMRkISP1 coloredlogs.install(level=logging.INFO, fmt='%(name)s %(levelname)s %(message)s') @@ -39,9 +40,10 @@ tuner.add(LSCRkISP1( smoothing_function=lt.smoothing.MedianBlur(3), )) tuner.add(AGCRkISP1(debug=[lt.Debug.Plot])) +tuner.add(CCMRkISP1(debug=[lt.Debug.Plot])) tuner.set_input_parser(YamlParser()) tuner.set_output_formatter(YamlOutput()) -tuner.set_output_order([AGCRkISP1, LSCRkISP1]) +tuner.set_output_order([AGCRkISP1, CCMRkISP1, LSCRkISP1]) if __name__ == '__main__': sys.exit(tuner.run(sys.argv))