[{"id":23767,"web_url":"https://patchwork.libcamera.org/comment/23767/","msgid":"<CAHW6GYKQECesnz+DdFMKg7Xz5Ek+vCe1ipc0w2fLba_gcNMZEw@mail.gmail.com>","date":"2022-07-06T11:52:32","subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi William\n\nThanks for the patch.\n\nOn Wed, 6 Jul 2022 at 11:18, David Plowman\n<david.plowman@raspberrypi.com> wrote:\n>\n> From: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n>\n> The ctt would not work if only passed alsc images.\n>\n> Added alsc_only.py to run alsc calibration only, and modified check_imgs\n> to allow for no macbeth chart images.\n>\n> Example usage would be ./alsc_only.py -i tuning-images/ -o sensor.json\n> with the same optional arguments as the original ctt.\n>\n> Signed-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n\nReviewed-by: David Plowman <david.plowman@raspberrypi.com>\n\nThanks!\nDavid\n\n> ---\n>  utils/raspberrypi/ctt/alsc_only.py | 118 +++++++++++++++++++++++++++++\n>  utils/raspberrypi/ctt/ctt.py       |   8 +-\n>  2 files changed, 124 insertions(+), 2 deletions(-)\n>  create mode 100755 utils/raspberrypi/ctt/alsc_only.py\n>\n> diff --git a/utils/raspberrypi/ctt/alsc_only.py b/utils/raspberrypi/ctt/alsc_only.py\n> new file mode 100755\n> index 00000000..318adc8c\n> --- /dev/null\n> +++ b/utils/raspberrypi/ctt/alsc_only.py\n> @@ -0,0 +1,118 @@\n> +#!/usr/bin/env python3\n> +#\n> +# SPDX-License-Identifier: BSD-2-Clause\n> +#\n> +# Copyright (C) 2022, Raspberry Pi (Trading) Limited\n> +#\n> +# alsc_only.py - alsc tuning tool\n> +\n> +from ctt import *\n> +\n> +\n> +def run_alsc(json_output, directory, config, log_output):\n> +    \"\"\"\n> +    check input files are jsons\n> +    \"\"\"\n> +    if json_output[-5:] != '.json':\n> +        raise ArgError('\\n\\nError: Output must be a json file!')\n> +    if config is not None:\n> +        \"\"\"\n> +        check if config file is actually a json\n> +        \"\"\"\n> +        if config[-5:] != '.json':\n> +            raise ArgError('\\n\\nError: Config file must be a json file!')\n> +        \"\"\"\n> +        read configurations\n> +        \"\"\"\n> +        try:\n> +            with open(config, 'r') as config_json:\n> +                configs = json.load(config_json)\n> +        except FileNotFoundError:\n> +            configs = {}\n> +            config = False\n> +        except json.decoder.JSONDecodeError:\n> +            configs = {}\n> +            config = True\n> +\n> +    else:\n> +        configs = {}\n> +    \"\"\"\n> +    load configurations from config file, if not given then set default\n> +    only load configurations needed for alsc, and directly define others\n> +    \"\"\"\n> +    plot = get_config(configs, \"plot\", [], 'list')\n> +    alsc_d = get_config(configs, \"alsc\", {}, 'dict')\n> +    do_alsc_colour = get_config(alsc_d, \"do_alsc_colour\", 1, 'bool')\n> +    luminance_strength = get_config(alsc_d, \"luminance_strength\", 0.5, 'num')\n> +    blacklevel = get_config(configs, \"blacklevel\", -1, 'num')\n> +    mac_config = (0, 0)\n> +\n> +    if blacklevel < -1 or blacklevel >= 2**16:\n> +        print('\\nInvalid blacklevel, defaulted to 64')\n> +        blacklevel = -1\n> +\n> +    if luminance_strength < 0 or luminance_strength > 1:\n> +        print('\\nInvalid luminance_strength strength, defaulted to 0.5')\n> +        luminance_strength = 0.5\n> +\n> +    \"\"\"\n> +    sanitise directory path\n> +    \"\"\"\n> +    if directory[-1] != '/':\n> +        directory += '/'\n> +    \"\"\"\n> +    initialise tuning tool and load images\n> +    \"\"\"\n> +    try:\n> +        Cam = Camera(json_output)\n> +        Cam.log_user_input(json_output, directory, config, log_output)\n> +        disable = set(Cam.json.keys()).symmetric_difference({\"rpi.alsc\"})\n> +        Cam.disable = disable\n> +        Cam.plot = plot\n> +        Cam.add_imgs(directory, mac_config, blacklevel)\n> +    except FileNotFoundError:\n> +        raise ArgError('\\n\\nError: Input image directory not found!')\n> +\n> +    \"\"\"\n> +    preform calibrations as long as check_imgs returns True\n> +    Only performs the alsc calibration\n> +    \"\"\"\n> +    if Cam.check_imgs(macbeth=False):\n> +        Cam.json_remove(disable)\n> +        print('\\nSTARTING CALIBRATIONS')\n> +        Cam.alsc_cal(luminance_strength, do_alsc_colour)\n> +        print('\\nFINISHED CALIBRATIONS')\n> +        Cam.write_json()\n> +        Cam.write_log(log_output)\n> +        print('\\nCalibrations written to: '+json_output)\n> +        if log_output is None:\n> +            log_output = 'ctt_log.txt'\n> +        print('Log file written to: '+log_output)\n> +        pass\n> +    else:\n> +        Cam.write_log(log_output)\n> +\n> +\n> +if __name__ == '__main__':\n> +    \"\"\"\n> +    initialise calibration\n> +    \"\"\"\n> +    if len(sys.argv) == 1:\n> +        print(\"\"\"\n> +    Pisp Camera Tuning Tool version 1.0\n> +\n> +    Required Arguments:\n> +    '-i' : Calibration image directory.\n> +    '-o' : Name of output json file.\n> +\n> +    Optional Arguments:\n> +    '-c' : Config file for the CTT. If not passed, default parameters used.\n> +    '-l' : Name of output log file. If not passed, 'ctt_log.txt' used.\n> +              \"\"\")\n> +        quit(0)\n> +    else:\n> +        \"\"\"\n> +        parse input arguments\n> +        \"\"\"\n> +        json_output, directory, config, log_output = parse_input()\n> +        run_alsc(json_output, directory, config, log_output)\n> diff --git a/utils/raspberrypi/ctt/ctt.py b/utils/raspberrypi/ctt/ctt.py\n> index 15064634..0ea4854d 100755\n> --- a/utils/raspberrypi/ctt/ctt.py\n> +++ b/utils/raspberrypi/ctt/ctt.py\n> @@ -664,7 +664,7 @@ class Camera:\n>          - incorrect filename/extension\n>          - images from different cameras\n>      \"\"\"\n> -    def check_imgs(self):\n> +    def check_imgs(self, macbeth=True):\n>          self.log += '\\n\\nImages found:'\n>          self.log += '\\nMacbeth : {}'.format(len(self.imgs))\n>          self.log += '\\nALSC : {} '.format(len(self.imgs_alsc))\n> @@ -672,10 +672,14 @@ class Camera:\n>          \"\"\"\n>          check usable images found\n>          \"\"\"\n> -        if len(self.imgs) == 0:\n> +        if len(self.imgs) == 0 and macbeth:\n>              print('\\nERROR: No usable macbeth chart images found')\n>              self.log += '\\nERROR: No usable macbeth chart images found'\n>              return 0\n> +        elif len(self.imgs) == 0 and len(self.imgs_alsc) == 0:\n> +            print('\\nERROR: No usable images found')\n> +            self.log += '\\nERROR: No usable images found'\n> +            return 0\n>          \"\"\"\n>          Double check that every image has come from the same camera...\n>          \"\"\"\n> --\n> 2.30.2\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 54349BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  6 Jul 2022 11:52:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8F2316330E;\n\tWed,  6 Jul 2022 13:52:45 +0200 (CEST)","from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com\n\t[IPv6:2a00:1450:4864:20::62c])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C47A860403\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  6 Jul 2022 13:52:43 +0200 (CEST)","by mail-ej1-x62c.google.com with SMTP id u12so26628741eja.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 06 Jul 2022 04:52:43 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1657108365;\n\tbh=P8cDOmzr8QDalvcQY8TQGiZQTjZgxWZF5lajGN1mfCI=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=3SV5+lNqiTOaMRdEJgifbNl0ZUpJMLiJX3PJzWDkKsnhHUM62K9uQW3lmODGErAVN\n\tTInEeVyMt5Ehu3lwdYSdrls9y0V20HLqkeYX5ntg8QjmVH1VffIjurzfdIVaU0gl/D\n\tYuwcxG/LutB8drkD92qG2KE9rWokEqv9wfIY7O3dXUXXGKZw8PJuyGPO3rBYIOEFVs\n\towgLrQjcmGnhFKwTpVYCeTPZbzYdrG93DpoPBndCCPhPMPlXh5d88+iaU3afOeQ5Cw\n\tARZwDL7/Bw0jop05F1IIZyqAbyhbN3A/XEde8JH2KCiapFDuwaTcKp7X0HHPEXqam5\n\tZIiftZh7SdjZQ==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to;\n\tbh=kilje/TF/bHUyQ1xAj3EE28q5WFS8czCoY/4ZQMMCfg=;\n\tb=XZbn0m2erp3fQtpCpeFXNhv09X7RENoxraSSPgnkDUzPdbo3jI7lhpYDXXiPFpUFSQ\n\tRMI8q8MHEcgdIrFN8lod+VXLnT22zJDPLRGF/GfRtTn1E066F6/I6bKDsmyx8M/6U5kz\n\tJH7ahQH2Oxo2eVB9e4o0e6F99q0M4aGZ2bRG+Hk0B7uevoVnm/W+9NscnC8WCxhTcglo\n\tDbw29pCSr9doIF0DWsSP9tVG0lpYBe7kOCz+w4E4ZmcakCIsZZGEXDC7Hb2Tl/ttHa/l\n\tzKk76qoWggCOsOvk7J4XEZ15kyyVebs/cbF6JvUfU6RcmXw/lWlsab+EzlE9xP+OEzyZ\n\tKrqg=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"XZbn0m2e\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to;\n\tbh=kilje/TF/bHUyQ1xAj3EE28q5WFS8czCoY/4ZQMMCfg=;\n\tb=7lvgOJ2CAq41pbhSK+682bYaqWUJesK5AqwToSbLSaGKSY6Eix8dy9izFv8CseTWbq\n\tTkSkjeUeBkPIoPz22yVqbvZu5afkra5/dnW/zQtQXMxpi4BWqfGNrM1j1II9o+uduhE1\n\ttBBgzsyV/saMihvjuZmS4cxygeoLrvEBil4cSqvFI2Jnl/E4Ta82oS72UCS5S6711Nob\n\tVrOVaov8g1jHtOfr56SJE+tXG1YixMPekqBcnE+wCo1WaXsIJzwAB9m+7QXsqzopcfYi\n\tM9Tpd/LES7j4fBsvlUDX8oh45hCCtGl6q2H5H1NLCRhrZu2O2dy6zUi5JFF4U9EiOMtQ\n\tjEOw==","X-Gm-Message-State":"AJIora9O6OXpYHKiUkOkvelXYY9gkoOn+GJzhjBE63mc4PnTbWoWMGDQ\n\tV7+4Rc1gyiTFm18EnSqn8DfMVqoA4n5Qq+en4GnydvjEIz8=","X-Google-Smtp-Source":"AGRyM1tuA49rnLHD+urEvBRu/YeUNURyreWWCMnVWlWa671OWUAe281AkXnd+P19IdF6ITEZaWiDPCdJ3uwz8IQGMQ4=","X-Received":"by 2002:a17:906:478e:b0:722:fc31:aa13 with SMTP id\n\tcw14-20020a170906478e00b00722fc31aa13mr39520373ejc.84.1657108363027;\n\tWed, 06 Jul 2022 04:52:43 -0700 (PDT)","MIME-Version":"1.0","References":"<20220706101836.20153-1-david.plowman@raspberrypi.com>\n\t<20220706101836.20153-3-david.plowman@raspberrypi.com>","In-Reply-To":"<20220706101836.20153-3-david.plowman@raspberrypi.com>","Date":"Wed, 6 Jul 2022 12:52:32 +0100","Message-ID":"<CAHW6GYKQECesnz+DdFMKg7Xz5Ek+vCe1ipc0w2fLba_gcNMZEw@mail.gmail.com>","To":"libcamera devel <libcamera-devel@lists.libcamera.org>, \n\tWilliam Vinnicombe <william.vinnicombe@raspberrypi.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"David Plowman via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"David Plowman <david.plowman@raspberrypi.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23772,"web_url":"https://patchwork.libcamera.org/comment/23772/","msgid":"<YsXJrpkkrRL/tGsU@pendragon.ideasonboard.com>","date":"2022-07-06T17:43:10","subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David and William,\n\nThank you for the patch.\n\nOn Wed, Jul 06, 2022 at 11:18:35AM +0100, David Plowman via libcamera-devel wrote:\n> From: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n> \n> The ctt would not work if only passed alsc images.\n> \n> Added alsc_only.py to run alsc calibration only, and modified check_imgs\n> to allow for no macbeth chart images.\n\nThe commit message should use the present tense, as it describes what is\nbeing done. s/Added/Add/ and s/modified/modify/.\n\n> Example usage would be ./alsc_only.py -i tuning-images/ -o sensor.json\n> with the same optional arguments as the original ctt.\n> \n> Signed-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n> ---\n>  utils/raspberrypi/ctt/alsc_only.py | 118 +++++++++++++++++++++++++++++\n>  utils/raspberrypi/ctt/ctt.py       |   8 +-\n>  2 files changed, 124 insertions(+), 2 deletions(-)\n>  create mode 100755 utils/raspberrypi/ctt/alsc_only.py\n> \n> diff --git a/utils/raspberrypi/ctt/alsc_only.py b/utils/raspberrypi/ctt/alsc_only.py\n> new file mode 100755\n> index 00000000..318adc8c\n> --- /dev/null\n> +++ b/utils/raspberrypi/ctt/alsc_only.py\n> @@ -0,0 +1,118 @@\n> +#!/usr/bin/env python3\n> +#\n> +# SPDX-License-Identifier: BSD-2-Clause\n> +#\n> +# Copyright (C) 2022, Raspberry Pi (Trading) Limited\n> +#\n> +# alsc_only.py - alsc tuning tool\n> +\n> +from ctt import *\n> +\n> +\n> +def run_alsc(json_output, directory, config, log_output):\n> +    \"\"\"\n> +    check input files are jsons\n> +    \"\"\"\n> +    if json_output[-5:] != '.json':\n> +        raise ArgError('\\n\\nError: Output must be a json file!')\n> +    if config is not None:\n> +        \"\"\"\n> +        check if config file is actually a json\n> +        \"\"\"\n> +        if config[-5:] != '.json':\n> +            raise ArgError('\\n\\nError: Config file must be a json file!')\n> +        \"\"\"\n> +        read configurations\n> +        \"\"\"\n> +        try:\n> +            with open(config, 'r') as config_json:\n> +                configs = json.load(config_json)\n> +        except FileNotFoundError:\n> +            configs = {}\n> +            config = False\n> +        except json.decoder.JSONDecodeError:\n> +            configs = {}\n> +            config = True\n> +\n> +    else:\n> +        configs = {}\n> +    \"\"\"\n> +    load configurations from config file, if not given then set default\n> +    only load configurations needed for alsc, and directly define others\n> +    \"\"\"\n> +    plot = get_config(configs, \"plot\", [], 'list')\n> +    alsc_d = get_config(configs, \"alsc\", {}, 'dict')\n> +    do_alsc_colour = get_config(alsc_d, \"do_alsc_colour\", 1, 'bool')\n> +    luminance_strength = get_config(alsc_d, \"luminance_strength\", 0.5, 'num')\n> +    blacklevel = get_config(configs, \"blacklevel\", -1, 'num')\n> +    mac_config = (0, 0)\n> +\n> +    if blacklevel < -1 or blacklevel >= 2**16:\n> +        print('\\nInvalid blacklevel, defaulted to 64')\n> +        blacklevel = -1\n> +\n> +    if luminance_strength < 0 or luminance_strength > 1:\n> +        print('\\nInvalid luminance_strength strength, defaulted to 0.5')\n> +        luminance_strength = 0.5\n> +\n> +    \"\"\"\n> +    sanitise directory path\n> +    \"\"\"\n> +    if directory[-1] != '/':\n> +        directory += '/'\n> +    \"\"\"\n> +    initialise tuning tool and load images\n> +    \"\"\"\n> +    try:\n> +        Cam = Camera(json_output)\n> +        Cam.log_user_input(json_output, directory, config, log_output)\n> +        disable = set(Cam.json.keys()).symmetric_difference({\"rpi.alsc\"})\n> +        Cam.disable = disable\n> +        Cam.plot = plot\n> +        Cam.add_imgs(directory, mac_config, blacklevel)\n> +    except FileNotFoundError:\n> +        raise ArgError('\\n\\nError: Input image directory not found!')\n> +\n> +    \"\"\"\n> +    preform calibrations as long as check_imgs returns True\n> +    Only performs the alsc calibration\n> +    \"\"\"\n> +    if Cam.check_imgs(macbeth=False):\n> +        Cam.json_remove(disable)\n> +        print('\\nSTARTING CALIBRATIONS')\n> +        Cam.alsc_cal(luminance_strength, do_alsc_colour)\n> +        print('\\nFINISHED CALIBRATIONS')\n> +        Cam.write_json()\n> +        Cam.write_log(log_output)\n> +        print('\\nCalibrations written to: '+json_output)\n> +        if log_output is None:\n> +            log_output = 'ctt_log.txt'\n> +        print('Log file written to: '+log_output)\n> +        pass\n> +    else:\n> +        Cam.write_log(log_output)\n\nThis duplicates quite a bit of code from run_ctt(). Could we make\nrun_ctt() more modular instead ?\n\n> +\n> +\n> +if __name__ == '__main__':\n> +    \"\"\"\n> +    initialise calibration\n> +    \"\"\"\n> +    if len(sys.argv) == 1:\n> +        print(\"\"\"\n> +    Pisp Camera Tuning Tool version 1.0\n> +\n> +    Required Arguments:\n> +    '-i' : Calibration image directory.\n> +    '-o' : Name of output json file.\n> +\n> +    Optional Arguments:\n> +    '-c' : Config file for the CTT. If not passed, default parameters used.\n> +    '-l' : Name of output log file. If not passed, 'ctt_log.txt' used.\n> +              \"\"\")\n> +        quit(0)\n> +    else:\n> +        \"\"\"\n> +        parse input arguments\n> +        \"\"\"\n> +        json_output, directory, config, log_output = parse_input()\n> +        run_alsc(json_output, directory, config, log_output)\n> diff --git a/utils/raspberrypi/ctt/ctt.py b/utils/raspberrypi/ctt/ctt.py\n> index 15064634..0ea4854d 100755\n> --- a/utils/raspberrypi/ctt/ctt.py\n> +++ b/utils/raspberrypi/ctt/ctt.py\n> @@ -664,7 +664,7 @@ class Camera:\n>          - incorrect filename/extension\n>          - images from different cameras\n>      \"\"\"\n> -    def check_imgs(self):\n> +    def check_imgs(self, macbeth=True):\n>          self.log += '\\n\\nImages found:'\n>          self.log += '\\nMacbeth : {}'.format(len(self.imgs))\n>          self.log += '\\nALSC : {} '.format(len(self.imgs_alsc))\n> @@ -672,10 +672,14 @@ class Camera:\n>          \"\"\"\n>          check usable images found\n>          \"\"\"\n> -        if len(self.imgs) == 0:\n> +        if len(self.imgs) == 0 and macbeth:\n>              print('\\nERROR: No usable macbeth chart images found')\n>              self.log += '\\nERROR: No usable macbeth chart images found'\n>              return 0\n> +        elif len(self.imgs) == 0 and len(self.imgs_alsc) == 0:\n> +            print('\\nERROR: No usable images found')\n> +            self.log += '\\nERROR: No usable images found'\n> +            return 0\n>          \"\"\"\n>          Double check that every image has come from the same camera...\n>          \"\"\"","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 43EE2BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  6 Jul 2022 17:43:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 97B2E63310;\n\tWed,  6 Jul 2022 19:43:36 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DC2FE60403\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  6 Jul 2022 19:43:35 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 54A6F30A;\n\tWed,  6 Jul 2022 19:43:35 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1657129416;\n\tbh=xe58jsSdx9taW0rzyffkWJfSbSIpeTOPVzoUdezf/i0=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=yjlHQ6klePh/iJN011aNvJ5UOqAMEoRMezuZGRKtNS2vO8eHPhc0Qa/PJe2vdhnpQ\n\tuTJR84VKmh0SedyNZXOx7tbw9t0mOs2XKowIpNgIVAfF+S+bBqJzrhx0MnwvnQIZCY\n\tKTMkxnWBDX4/6yr8NToX29Nb8VCsaxzFIbIyTDg6+6E5qTJ31SpNnGTSUOXL0v9+CP\n\tvARaD8JBL7ULkDCYVJFhLnOUh3gOTgCfpOXp8Oz9RYmvZkVBSdWOSmIyjy+j5fcYnc\n\tVI0zJMzisT3CrQCgYku5HKb6F4QviXcmESHit855w4P87BNGabMskI2/1B3SAVQT4b\n\ttSDUi+pHB/Jiw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1657129415;\n\tbh=xe58jsSdx9taW0rzyffkWJfSbSIpeTOPVzoUdezf/i0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=H6dderg9Ntq1Wxz2UMdH6pbz3yavvC9gmKe5zb7/2aRswxdC/MAqIWpm3damxUsfY\n\t/P+i5HRxN85SFAPZw5tYW02x/4Bd0ciYzW1SNaA60NP70YUrd7sR2yRRAtZapGqKe4\n\tWa3FWAI6FBsHrbI56mXVkwfXtITRysLj60RHDYFk="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"H6dderg9\"; dkim-atps=neutral","Date":"Wed, 6 Jul 2022 20:43:10 +0300","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<YsXJrpkkrRL/tGsU@pendragon.ideasonboard.com>","References":"<20220706101836.20153-1-david.plowman@raspberrypi.com>\n\t<20220706101836.20153-3-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220706101836.20153-3-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, william.vinnicombe@raspberrypi.com","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23814,"web_url":"https://patchwork.libcamera.org/comment/23814/","msgid":"<CAEmqJPrZRm89DQQQOZrusfKDouibzGBWBu8RHw_qmwD6=F3NvQ@mail.gmail.com>","date":"2022-07-11T09:40:20","subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi William,\n\nThank you for your work.\n\nOn Wed, 6 Jul 2022 at 11:18, David Plowman via libcamera-devel <\nlibcamera-devel@lists.libcamera.org> wrote:\n\n> From: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n>\n> The ctt would not work if only passed alsc images.\n>\n> Added alsc_only.py to run alsc calibration only, and modified check_imgs\n> to allow for no macbeth chart images.\n>\n> Example usage would be ./alsc_only.py -i tuning-images/ -o sensor.json\n> with the same optional arguments as the original ctt.\n>\n> Signed-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>\n>\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n\n> ---\n>  utils/raspberrypi/ctt/alsc_only.py | 118 +++++++++++++++++++++++++++++\n>  utils/raspberrypi/ctt/ctt.py       |   8 +-\n>  2 files changed, 124 insertions(+), 2 deletions(-)\n>  create mode 100755 utils/raspberrypi/ctt/alsc_only.py\n>\n> diff --git a/utils/raspberrypi/ctt/alsc_only.py\n> b/utils/raspberrypi/ctt/alsc_only.py\n> new file mode 100755\n> index 00000000..318adc8c\n> --- /dev/null\n> +++ b/utils/raspberrypi/ctt/alsc_only.py\n> @@ -0,0 +1,118 @@\n> +#!/usr/bin/env python3\n> +#\n> +# SPDX-License-Identifier: BSD-2-Clause\n> +#\n> +# Copyright (C) 2022, Raspberry Pi (Trading) Limited\n> +#\n> +# alsc_only.py - alsc tuning tool\n> +\n> +from ctt import *\n> +\n> +\n> +def run_alsc(json_output, directory, config, log_output):\n> +    \"\"\"\n> +    check input files are jsons\n> +    \"\"\"\n> +    if json_output[-5:] != '.json':\n> +        raise ArgError('\\n\\nError: Output must be a json file!')\n> +    if config is not None:\n> +        \"\"\"\n> +        check if config file is actually a json\n> +        \"\"\"\n> +        if config[-5:] != '.json':\n> +            raise ArgError('\\n\\nError: Config file must be a json file!')\n> +        \"\"\"\n> +        read configurations\n> +        \"\"\"\n> +        try:\n> +            with open(config, 'r') as config_json:\n> +                configs = json.load(config_json)\n> +        except FileNotFoundError:\n> +            configs = {}\n> +            config = False\n> +        except json.decoder.JSONDecodeError:\n> +            configs = {}\n> +            config = True\n> +\n> +    else:\n> +        configs = {}\n> +    \"\"\"\n> +    load configurations from config file, if not given then set default\n> +    only load configurations needed for alsc, and directly define others\n> +    \"\"\"\n> +    plot = get_config(configs, \"plot\", [], 'list')\n> +    alsc_d = get_config(configs, \"alsc\", {}, 'dict')\n> +    do_alsc_colour = get_config(alsc_d, \"do_alsc_colour\", 1, 'bool')\n> +    luminance_strength = get_config(alsc_d, \"luminance_strength\", 0.5,\n> 'num')\n> +    blacklevel = get_config(configs, \"blacklevel\", -1, 'num')\n> +    mac_config = (0, 0)\n> +\n> +    if blacklevel < -1 or blacklevel >= 2**16:\n> +        print('\\nInvalid blacklevel, defaulted to 64')\n> +        blacklevel = -1\n> +\n> +    if luminance_strength < 0 or luminance_strength > 1:\n> +        print('\\nInvalid luminance_strength strength, defaulted to 0.5')\n> +        luminance_strength = 0.5\n> +\n> +    \"\"\"\n> +    sanitise directory path\n> +    \"\"\"\n> +    if directory[-1] != '/':\n> +        directory += '/'\n> +    \"\"\"\n> +    initialise tuning tool and load images\n> +    \"\"\"\n> +    try:\n> +        Cam = Camera(json_output)\n> +        Cam.log_user_input(json_output, directory, config, log_output)\n> +        disable = set(Cam.json.keys()).symmetric_difference({\"rpi.alsc\"})\n> +        Cam.disable = disable\n> +        Cam.plot = plot\n> +        Cam.add_imgs(directory, mac_config, blacklevel)\n> +    except FileNotFoundError:\n> +        raise ArgError('\\n\\nError: Input image directory not found!')\n> +\n> +    \"\"\"\n> +    preform calibrations as long as check_imgs returns True\n> +    Only performs the alsc calibration\n> +    \"\"\"\n> +    if Cam.check_imgs(macbeth=False):\n> +        Cam.json_remove(disable)\n> +        print('\\nSTARTING CALIBRATIONS')\n> +        Cam.alsc_cal(luminance_strength, do_alsc_colour)\n> +        print('\\nFINISHED CALIBRATIONS')\n> +        Cam.write_json()\n> +        Cam.write_log(log_output)\n> +        print('\\nCalibrations written to: '+json_output)\n> +        if log_output is None:\n> +            log_output = 'ctt_log.txt'\n> +        print('Log file written to: '+log_output)\n> +        pass\n> +    else:\n> +        Cam.write_log(log_output)\n> +\n> +\n> +if __name__ == '__main__':\n> +    \"\"\"\n> +    initialise calibration\n> +    \"\"\"\n> +    if len(sys.argv) == 1:\n> +        print(\"\"\"\n> +    Pisp Camera Tuning Tool version 1.0\n> +\n> +    Required Arguments:\n> +    '-i' : Calibration image directory.\n> +    '-o' : Name of output json file.\n> +\n> +    Optional Arguments:\n> +    '-c' : Config file for the CTT. If not passed, default parameters\n> used.\n> +    '-l' : Name of output log file. If not passed, 'ctt_log.txt' used.\n> +              \"\"\")\n> +        quit(0)\n> +    else:\n> +        \"\"\"\n> +        parse input arguments\n> +        \"\"\"\n> +        json_output, directory, config, log_output = parse_input()\n> +        run_alsc(json_output, directory, config, log_output)\n> diff --git a/utils/raspberrypi/ctt/ctt.py b/utils/raspberrypi/ctt/ctt.py\n> index 15064634..0ea4854d 100755\n> --- a/utils/raspberrypi/ctt/ctt.py\n> +++ b/utils/raspberrypi/ctt/ctt.py\n> @@ -664,7 +664,7 @@ class Camera:\n>          - incorrect filename/extension\n>          - images from different cameras\n>      \"\"\"\n> -    def check_imgs(self):\n> +    def check_imgs(self, macbeth=True):\n>          self.log += '\\n\\nImages found:'\n>          self.log += '\\nMacbeth : {}'.format(len(self.imgs))\n>          self.log += '\\nALSC : {} '.format(len(self.imgs_alsc))\n> @@ -672,10 +672,14 @@ class Camera:\n>          \"\"\"\n>          check usable images found\n>          \"\"\"\n> -        if len(self.imgs) == 0:\n> +        if len(self.imgs) == 0 and macbeth:\n>              print('\\nERROR: No usable macbeth chart images found')\n>              self.log += '\\nERROR: No usable macbeth chart images found'\n>              return 0\n> +        elif len(self.imgs) == 0 and len(self.imgs_alsc) == 0:\n> +            print('\\nERROR: No usable images found')\n> +            self.log += '\\nERROR: No usable images found'\n> +            return 0\n>          \"\"\"\n>          Double check that every image has come from the same camera...\n>          \"\"\"\n> --\n> 2.30.2\n>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2183FBD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 11 Jul 2022 09:40:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D117463310;\n\tMon, 11 Jul 2022 11:40:35 +0200 (CEST)","from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com\n\t[IPv6:2a00:1450:4864:20::22e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 45DE660402\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 11 Jul 2022 11:40:34 +0200 (CEST)","by mail-lj1-x22e.google.com with SMTP id bx13so5530268ljb.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 11 Jul 2022 02:40:34 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1657532435;\n\tbh=Yzj/xaqR4/I3Fzi/edUqV9/BvVqD3A6T0I+0uVbtTYE=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=pC6rkmEIEoGu888029OiuAphdoKXVdoPfxRUG6G6KGdflk2E8YBgfurmyylps+dMY\n\tQLnUH/zU1b6LpZ81QU9NxWtvFZK3+s1q7JFmaNtN+YuhdSnd7aIF3WcloqknWGSz18\n\tpBeYqMoxAk2Fka0GSYQZGmyNRX8mrslFcGzQHVDKM/awv1NESNwtDuOMuDHKLxO4/v\n\tyM0PjyDv30vfUENczhU2fIstp1ury2cU4fkbGrAx+cZozQBdvTCs5IJP7JnPb9pFik\n\tBdb/YTCQ/Rlkvr5l78JTzRzS1w8plupdB7awt0pS0jwUIuxfbxbSfDY0sxaQGT0Tzp\n\t972YXoXJKrUmg==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=GjTMB9t6Y5foE+t9W7p6bf0eZI3zZaewjTwJDUjX5vw=;\n\tb=rMiHU+VJ5r051gY+LSeeLpEOm3IwtfA6IXJpwsAr4fF1cA/gkdba4Hn9gW7nUw6KJ5\n\tJWeESNLHVe50k4FpKqoOLew7xAU70kOQ/Udr4LzSbf2++l8RD6PO4ofWIP4r7EcWRMwX\n\tv6AjjsKn7gVhlsq/TMtDxE92SEkjjnwkjimt2R998j+OS3TlIW/NL13p4gJA9Rr8f0Df\n\tyMqvqX2Yy1IpKwNT+QniuK1I1FuH1A0+lOlwtdftaTP2rP2B/govw7ajH6IutTl1IKN+\n\tHydKbtBnXmKubhvp9XL0lCCmT/qpsai4yu0Sg2boD9IauEC+LOAJPcpNxwEWHT73muOI\n\thAQA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"rMiHU+VJ\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=GjTMB9t6Y5foE+t9W7p6bf0eZI3zZaewjTwJDUjX5vw=;\n\tb=at/rd+9goId6og4Q8YxGiWEp2YohIfQxamG1W4Xk2s+3rYzJbmNBLbpwZDO1FVquwW\n\t3lwGAmryK+eXjxqqJVj62lv8cSdpki2TUOpghUG3chAPh7TnW0eo70rYVGmN9dKUVHjQ\n\tosFVcAqaYwNhnjgV2FDT9eqBSbMbLPcIx3ysDKiL15MaA/yj02+puH5+MFfj6HrqJYKX\n\thD8RcUXKy8UlsUYkcqZo8IzTwUutyFLCOU3/DIkY36c/6Aq+26eSwV0BOwb/V21n114B\n\thtdecjE+la1opgTR2Ahtz6H1bULGZ2zOODUjdDvlLFZ3kofqABlwypdNskv2oVGCpNBU\n\tajGA==","X-Gm-Message-State":"AJIora9HJJ+KAWDgZRX9sCAElGm/kLCHaOHv5iH5T9MV2avaMbvcT89K\n\tBVnzVYKlSt+c1XZr5Z7h27V4kFM1eH4rikiTPhsKs0X1dLrZuw==","X-Google-Smtp-Source":"AGRyM1vYbC5SKX+vVSwuoMcgb257B7/SPhs6S8bYM08PI53JKGumhIZrbDbqbB4oftDqopxMkWCrTrCIbuIzw2AXaxI=","X-Received":"by 2002:a2e:9dd3:0:b0:25a:72ea:3a15 with SMTP id\n\tx19-20020a2e9dd3000000b0025a72ea3a15mr9110347ljj.29.1657532433563;\n\tMon, 11 Jul 2022 02:40:33 -0700 (PDT)","MIME-Version":"1.0","References":"<20220706101836.20153-1-david.plowman@raspberrypi.com>\n\t<20220706101836.20153-3-david.plowman@raspberrypi.com>","In-Reply-To":"<20220706101836.20153-3-david.plowman@raspberrypi.com>","Date":"Mon, 11 Jul 2022 10:40:20 +0100","Message-ID":"<CAEmqJPrZRm89DQQQOZrusfKDouibzGBWBu8RHw_qmwD6=F3NvQ@mail.gmail.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Content-Type":"multipart/alternative; boundary=\"000000000000e8143f05e3845703\"","Subject":"Re: [libcamera-devel] [PATCH 2/3] utils: raspberrypi: ctt: Add\n\talsc_only method","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>,\n\tWilliam Vinnicombe <william.vinnicombe@raspberrypi.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]