[{"id":33371,"web_url":"https://patchwork.libcamera.org/comment/33371/","msgid":"<173962465086.4068558.6433182700528765410@ping.linuxembedded.co.uk>","date":"2025-02-15T13:04:10","subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2025-01-23 11:40:58)\n> To support the bayesian AWB algorithm in libtuning, the necessary data\n> needs to be collected and written to the tuning file.\n> \n> Extend libtuning to calculate and output that additional data.\n> \n> Prior probabilities and AwbModes are manually specified and not\n> calculated in the tuning process. Add sample values from the RaspberryPi\n> tuning files to the example config file.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> \n> ---\n> \n> Changes in v2:\n> - Collected tags\n> - Fixed missing space\n> - Reworked commit message\n> - Add example prior probabilities from RaspberryPi\n> ---\n>  utils/tuning/config-example.yaml             | 44 +++++++++++++++++++-\n>  utils/tuning/libtuning/modules/awb/awb.py    | 16 ++++---\n>  utils/tuning/libtuning/modules/awb/rkisp1.py | 21 +++++++---\n>  3 files changed, 68 insertions(+), 13 deletions(-)\n> \n> diff --git a/utils/tuning/config-example.yaml b/utils/tuning/config-example.yaml\n> index 1b7f52cd2fff..1bbb275778dc 100644\n> --- a/utils/tuning/config-example.yaml\n> +++ b/utils/tuning/config-example.yaml\n> @@ -5,7 +5,49 @@ general:\n>      do_alsc_colour: 1\n>      luminance_strength: 0.5\n>    awb:\n> -    greyworld: 0\n> +    # Algorithm can either be 'grey' or 'bayes'\n> +    algorithm: bayes\n> +    # Priors is only used for the bayes algorithm. They are defined in\n> +    # logarithmic space. A good staring point is:\n> +    # - lux: 0\n> +    #   ct: [ 2000, 3000, 13000 ]\n> +    #   probability: [ 1.0, 0.0, 0.0 ]\n> +    # - lux: 800\n> +    #   ct: [ 2000, 6000, 13000 ]\n> +    #   probability: [ 0.0, 2.0, 2.0 ]\n> +    # - lux: 1500\n> +    #   ct: [ 2000, 4000, 6000, 6500, 7000, 13000 ]\n> +    #   probability: [ 0.0, 1.0, 6.0, 7.0, 1.0, 1.0 ]\n> +    priors:\n> +      - lux: 0\n> +        ct: [ 2000, 13000 ]\n> +        probability: [ 0.0, 0.0 ]\n> +    AwbMode:\n> +      AwbAuto:\n> +        lo: 2500\n> +        hi: 8000\n> +      AwbIncandescent:\n> +        lo: 2500\n> +        hi: 3000\n> +      AwbTungsten:\n> +        lo: 3000\n> +        hi: 3500\n> +      AwbFluorescent:\n> +        lo: 4000\n> +        hi: 4700\n> +      AwbIndoor:\n> +        lo: 3000\n> +        hi: 5000\n> +      AwbDaylight:\n> +        lo: 5500\n> +        hi: 6500\n> +      AwbCloudy:\n> +        lo: 6500\n> +        hi: 8000\n> +      # One custom mode can be defined if needed\n> +      #AwbCustom:\n> +      #  lo: 2000\n> +      #  hi: 1300\n>    macbeth:\n>      small: 1\n>      show: 0\n> diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py\n> index c154cf3b8609..0dc4f59dcb26 100644\n> --- a/utils/tuning/libtuning/modules/awb/awb.py\n> +++ b/utils/tuning/libtuning/modules/awb/awb.py\n> @@ -27,10 +27,14 @@ class AWB(Module):\n>  \n>          imgs = [img for img in images if img.macbeth is not None]\n>  \n> -        gains, _, _ = awb(imgs, None, None, False)\n> -        gains = np.reshape(gains, (-1, 3))\n> +        ct_curve, transverse_pos, transverse_neg = awb(imgs, None, None, False)\n> +        ct_curve = np.reshape(ct_curve, (-1, 3))\n> +        gains = [{\n> +            'ct': int(v[0]),\n> +            'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> +        } for v in ct_curve]\n> +\n> +        return {'colourGains': gains,\n> +                'transversePos': transverse_pos,\n> +                'transverseNeg': transverse_neg}\n>  \n> -        return [{\n> -                    'ct': int(v[0]),\n> -                    'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> -                } for v in gains]\n> diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> index 0c95843b83d3..d562d26eb8cc 100644\n> --- a/utils/tuning/libtuning/modules/awb/rkisp1.py\n> +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> @@ -6,9 +6,6 @@\n>  \n>  from .awb import AWB\n>  \n> -import libtuning as lt\n> -\n> -\n>  class AWBRkISP1(AWB):\n>      hr_name = 'AWB (RkISP1)'\n>      out_name = 'Awb'\n> @@ -20,8 +17,20 @@ class AWBRkISP1(AWB):\n>          return True\n>  \n>      def process(self, config: dict, images: list, outputs: dict) -> dict:\n> -        output = {}\n> -\n> -        output['colourGains'] = self.do_calculation(images)\n> +        if not 'awb' in config['general']:\n> +            raise ValueError('AWB configuration missing')\n> +        awb_config = config['general']['awb']\n> +        algorithm = awb_config['algorithm']\n> +\n> +        output = {'algorithm': algorithm}\n> +        data = self.do_calculation(images)\n> +        if algorithm == 'grey':\n> +            output['colourGains'] = data['colourGains']\n\nHow come there's no output.update(data) on this code path ? (I don't\nknow what it does yet, just noticing that it's only on one path).\n\nIs there any argument to output the colourGains for greyworld as well as\nbayes to the same file ? or is Manual ColourTemperature handled\ndistinctly with bayes (I presume it just overrides whatever the bayes\nwould have predicted to be the colour temperature)\n\n\n> +        elif algorithm == 'bayes':\n> +            output['AwbMode'] = awb_config['AwbMode']\n> +            output['priors'] = awb_config['priors']\n> +            output.update(data)\n> +        else:\n> +            raise ValueError(f\"Unknown AWB algorithm {output['algorithm']}\")\n>  \n>          return output\n> -- \n> 2.43.0\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 C83B3C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 15 Feb 2025 13:04:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A6E0A68659;\n\tSat, 15 Feb 2025 14:04:15 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F2C9561862\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 15 Feb 2025 14:04:13 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E3D3521C;\n\tSat, 15 Feb 2025 14:02:53 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"qe1HVOy6\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1739624574;\n\tbh=w1LnTPs9XQT83Un8BcO2Mu3jjpKieBq3MQsJS6hbQDU=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=qe1HVOy6aVKfybGvmL8HMsnFjGL+04wgte3pa9jTkaGscD6nKfviB/GPa7ABF3OBh\n\t4Acrw/jRa7gM8QMhjda3Clugd/BBjnDkw17srWQfr8N5gQQFhG94belomKfIn+sTAo\n\tDN/KnyaV0MucaZXDwGFtFhBqWtSvGicaIuUcMi3k=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250123114204.79321-9-stefan.klug@ideasonboard.com>","References":"<20250123114204.79321-1-stefan.klug@ideasonboard.com>\n\t<20250123114204.79321-9-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Sat, 15 Feb 2025 13:04:10 +0000","Message-ID":"<173962465086.4068558.6433182700528765410@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33374,"web_url":"https://patchwork.libcamera.org/comment/33374/","msgid":"<4njef35wyqt6qz2oul4yjg62ewedeebq6l5tksbgby5f3azzlh@wlzmlh6z62ql>","date":"2025-02-17T09:04:41","subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the review. \n\nOn Sat, Feb 15, 2025 at 01:04:10PM +0000, Kieran Bingham wrote:\n> Quoting Stefan Klug (2025-01-23 11:40:58)\n> > To support the bayesian AWB algorithm in libtuning, the necessary data\n> > needs to be collected and written to the tuning file.\n> > \n> > Extend libtuning to calculate and output that additional data.\n> > \n> > Prior probabilities and AwbModes are manually specified and not\n> > calculated in the tuning process. Add sample values from the RaspberryPi\n> > tuning files to the example config file.\n> > \n> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > \n> > ---\n> > \n> > Changes in v2:\n> > - Collected tags\n> > - Fixed missing space\n> > - Reworked commit message\n> > - Add example prior probabilities from RaspberryPi\n> > ---\n> >  utils/tuning/config-example.yaml             | 44 +++++++++++++++++++-\n> >  utils/tuning/libtuning/modules/awb/awb.py    | 16 ++++---\n> >  utils/tuning/libtuning/modules/awb/rkisp1.py | 21 +++++++---\n> >  3 files changed, 68 insertions(+), 13 deletions(-)\n> > \n> > diff --git a/utils/tuning/config-example.yaml b/utils/tuning/config-example.yaml\n> > index 1b7f52cd2fff..1bbb275778dc 100644\n> > --- a/utils/tuning/config-example.yaml\n> > +++ b/utils/tuning/config-example.yaml\n> > @@ -5,7 +5,49 @@ general:\n> >      do_alsc_colour: 1\n> >      luminance_strength: 0.5\n> >    awb:\n> > -    greyworld: 0\n> > +    # Algorithm can either be 'grey' or 'bayes'\n> > +    algorithm: bayes\n> > +    # Priors is only used for the bayes algorithm. They are defined in\n> > +    # logarithmic space. A good staring point is:\n> > +    # - lux: 0\n> > +    #   ct: [ 2000, 3000, 13000 ]\n> > +    #   probability: [ 1.0, 0.0, 0.0 ]\n> > +    # - lux: 800\n> > +    #   ct: [ 2000, 6000, 13000 ]\n> > +    #   probability: [ 0.0, 2.0, 2.0 ]\n> > +    # - lux: 1500\n> > +    #   ct: [ 2000, 4000, 6000, 6500, 7000, 13000 ]\n> > +    #   probability: [ 0.0, 1.0, 6.0, 7.0, 1.0, 1.0 ]\n> > +    priors:\n> > +      - lux: 0\n> > +        ct: [ 2000, 13000 ]\n> > +        probability: [ 0.0, 0.0 ]\n> > +    AwbMode:\n> > +      AwbAuto:\n> > +        lo: 2500\n> > +        hi: 8000\n> > +      AwbIncandescent:\n> > +        lo: 2500\n> > +        hi: 3000\n> > +      AwbTungsten:\n> > +        lo: 3000\n> > +        hi: 3500\n> > +      AwbFluorescent:\n> > +        lo: 4000\n> > +        hi: 4700\n> > +      AwbIndoor:\n> > +        lo: 3000\n> > +        hi: 5000\n> > +      AwbDaylight:\n> > +        lo: 5500\n> > +        hi: 6500\n> > +      AwbCloudy:\n> > +        lo: 6500\n> > +        hi: 8000\n> > +      # One custom mode can be defined if needed\n> > +      #AwbCustom:\n> > +      #  lo: 2000\n> > +      #  hi: 1300\n> >    macbeth:\n> >      small: 1\n> >      show: 0\n> > diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py\n> > index c154cf3b8609..0dc4f59dcb26 100644\n> > --- a/utils/tuning/libtuning/modules/awb/awb.py\n> > +++ b/utils/tuning/libtuning/modules/awb/awb.py\n> > @@ -27,10 +27,14 @@ class AWB(Module):\n> >  \n> >          imgs = [img for img in images if img.macbeth is not None]\n> >  \n> > -        gains, _, _ = awb(imgs, None, None, False)\n> > -        gains = np.reshape(gains, (-1, 3))\n> > +        ct_curve, transverse_pos, transverse_neg = awb(imgs, None, None, False)\n> > +        ct_curve = np.reshape(ct_curve, (-1, 3))\n> > +        gains = [{\n> > +            'ct': int(v[0]),\n> > +            'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> > +        } for v in ct_curve]\n> > +\n> > +        return {'colourGains': gains,\n> > +                'transversePos': transverse_pos,\n> > +                'transverseNeg': transverse_neg}\n> >  \n> > -        return [{\n> > -                    'ct': int(v[0]),\n> > -                    'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> > -                } for v in gains]\n> > diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > index 0c95843b83d3..d562d26eb8cc 100644\n> > --- a/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > @@ -6,9 +6,6 @@\n> >  \n> >  from .awb import AWB\n> >  \n> > -import libtuning as lt\n> > -\n> > -\n> >  class AWBRkISP1(AWB):\n> >      hr_name = 'AWB (RkISP1)'\n> >      out_name = 'Awb'\n> > @@ -20,8 +17,20 @@ class AWBRkISP1(AWB):\n> >          return True\n> >  \n> >      def process(self, config: dict, images: list, outputs: dict) -> dict:\n> > -        output = {}\n> > -\n> > -        output['colourGains'] = self.do_calculation(images)\n> > +        if not 'awb' in config['general']:\n> > +            raise ValueError('AWB configuration missing')\n> > +        awb_config = config['general']['awb']\n> > +        algorithm = awb_config['algorithm']\n> > +\n> > +        output = {'algorithm': algorithm}\n> > +        data = self.do_calculation(images)\n> > +        if algorithm == 'grey':\n> > +            output['colourGains'] = data['colourGains']\n> \n> How come there's no output.update(data) on this code path ? (I don't\n> know what it does yet, just noticing that it's only on one path).\n\nArguably in the tuning code there is room for improvement :-). Reason is\nthat in the grey world case, we only need the colourGains in the tuning\nfile, in the bayes case we need all the results, so I just did\noutput.update(data) without manually stating every key.\n\n> \n> Is there any argument to output the colourGains for greyworld as well as\n> bayes to the same file ? or is Manual ColourTemperature handled\n> distinctly with bayes (I presume it just overrides whatever the bayes\n> would have predicted to be the colour temperature)\n> \n\nI'm not sure if I completely understand what you mean here. colourGains\nare needed for both cases (grey and bayes). But bayes needs the rest.\nWould you prefer the following code?\n\nif algorithm == 'grey':\n    output['colourGains'] = data['colourGains']\nelif algorithm == 'bayes':\n    output['AwbMode'] = awb_config['AwbMode']\n    output['priors'] = awb_config['priors']\n    output['colourGains'] = data['colourGains']\n    output['transversePos'] = data['transversePos']\n    output['transverseNeg'] = data['transverseNeg']\nelse:\n...\n\n\nBest regards,\nStefan\n\n> \n> > +        elif algorithm == 'bayes':\n> > +            output['AwbMode'] = awb_config['AwbMode']\n> > +            output['priors'] = awb_config['priors']\n> > +            output.update(data)\n> > +        else:\n> > +            raise ValueError(f\"Unknown AWB algorithm {output['algorithm']}\")\n> >  \n> >          return output\n> > -- \n> > 2.43.0\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 10B52BE08B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 17 Feb 2025 09:04:48 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AC39F68661;\n\tMon, 17 Feb 2025 10:04:46 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4D41A61861\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 17 Feb 2025 10:04:44 +0100 (CET)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:b47f:e20a:c4c7:ece1])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EB476842;\n\tMon, 17 Feb 2025 10:03:22 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Jj6gXP2j\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1739783003;\n\tbh=ogsC4LH/6RbS30FS1tk6lkxi2V/p/DM/dTGjT/92oq0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Jj6gXP2jQsTflIjTRJ9TMIkyMYYRB+FxKV+2+MrPc23OS/Ip1AxcMdN/7hueH/fEc\n\t/vcoe5ISlTRhRo+qli59WTuE9Sk5Odg+QsOvjsHAW5Vv9iJx3j9GAEiMy2jIbRxz2Y\n\tbtmMpYASAb0Wau4rdgOk0E0ISFMlJZ1/LK41aZIg=","Date":"Mon, 17 Feb 2025 10:04:41 +0100","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tPaul Elder <paul.elder@ideasonboard.com>","Subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","Message-ID":"<4njef35wyqt6qz2oul4yjg62ewedeebq6l5tksbgby5f3azzlh@wlzmlh6z62ql>","References":"<20250123114204.79321-1-stefan.klug@ideasonboard.com>\n\t<20250123114204.79321-9-stefan.klug@ideasonboard.com>\n\t<173962465086.4068558.6433182700528765410@ping.linuxembedded.co.uk>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<173962465086.4068558.6433182700528765410@ping.linuxembedded.co.uk>","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33410,"web_url":"https://patchwork.libcamera.org/comment/33410/","msgid":"<174005293535.3771432.1558519353475570810@ping.linuxembedded.co.uk>","date":"2025-02-20T12:02:15","subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2025-02-17 09:04:41)\n> Hi Kieran,\n> \n> Thank you for the review. \n> \n> On Sat, Feb 15, 2025 at 01:04:10PM +0000, Kieran Bingham wrote:\n> > Quoting Stefan Klug (2025-01-23 11:40:58)\n> > > To support the bayesian AWB algorithm in libtuning, the necessary data\n> > > needs to be collected and written to the tuning file.\n> > > \n> > > Extend libtuning to calculate and output that additional data.\n> > > \n> > > Prior probabilities and AwbModes are manually specified and not\n> > > calculated in the tuning process. Add sample values from the RaspberryPi\n> > > tuning files to the example config file.\n> > > \n> > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > \n> > > ---\n> > > \n> > > Changes in v2:\n> > > - Collected tags\n> > > - Fixed missing space\n> > > - Reworked commit message\n> > > - Add example prior probabilities from RaspberryPi\n> > > ---\n> > >  utils/tuning/config-example.yaml             | 44 +++++++++++++++++++-\n> > >  utils/tuning/libtuning/modules/awb/awb.py    | 16 ++++---\n> > >  utils/tuning/libtuning/modules/awb/rkisp1.py | 21 +++++++---\n> > >  3 files changed, 68 insertions(+), 13 deletions(-)\n> > > \n> > > diff --git a/utils/tuning/config-example.yaml b/utils/tuning/config-example.yaml\n> > > index 1b7f52cd2fff..1bbb275778dc 100644\n> > > --- a/utils/tuning/config-example.yaml\n> > > +++ b/utils/tuning/config-example.yaml\n> > > @@ -5,7 +5,49 @@ general:\n> > >      do_alsc_colour: 1\n> > >      luminance_strength: 0.5\n> > >    awb:\n> > > -    greyworld: 0\n> > > +    # Algorithm can either be 'grey' or 'bayes'\n> > > +    algorithm: bayes\n> > > +    # Priors is only used for the bayes algorithm. They are defined in\n> > > +    # logarithmic space. A good staring point is:\n> > > +    # - lux: 0\n> > > +    #   ct: [ 2000, 3000, 13000 ]\n> > > +    #   probability: [ 1.0, 0.0, 0.0 ]\n> > > +    # - lux: 800\n> > > +    #   ct: [ 2000, 6000, 13000 ]\n> > > +    #   probability: [ 0.0, 2.0, 2.0 ]\n> > > +    # - lux: 1500\n> > > +    #   ct: [ 2000, 4000, 6000, 6500, 7000, 13000 ]\n> > > +    #   probability: [ 0.0, 1.0, 6.0, 7.0, 1.0, 1.0 ]\n> > > +    priors:\n> > > +      - lux: 0\n> > > +        ct: [ 2000, 13000 ]\n> > > +        probability: [ 0.0, 0.0 ]\n> > > +    AwbMode:\n> > > +      AwbAuto:\n> > > +        lo: 2500\n> > > +        hi: 8000\n> > > +      AwbIncandescent:\n> > > +        lo: 2500\n> > > +        hi: 3000\n> > > +      AwbTungsten:\n> > > +        lo: 3000\n> > > +        hi: 3500\n> > > +      AwbFluorescent:\n> > > +        lo: 4000\n> > > +        hi: 4700\n> > > +      AwbIndoor:\n> > > +        lo: 3000\n> > > +        hi: 5000\n> > > +      AwbDaylight:\n> > > +        lo: 5500\n> > > +        hi: 6500\n> > > +      AwbCloudy:\n> > > +        lo: 6500\n> > > +        hi: 8000\n> > > +      # One custom mode can be defined if needed\n> > > +      #AwbCustom:\n> > > +      #  lo: 2000\n> > > +      #  hi: 1300\n> > >    macbeth:\n> > >      small: 1\n> > >      show: 0\n> > > diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py\n> > > index c154cf3b8609..0dc4f59dcb26 100644\n> > > --- a/utils/tuning/libtuning/modules/awb/awb.py\n> > > +++ b/utils/tuning/libtuning/modules/awb/awb.py\n> > > @@ -27,10 +27,14 @@ class AWB(Module):\n> > >  \n> > >          imgs = [img for img in images if img.macbeth is not None]\n> > >  \n> > > -        gains, _, _ = awb(imgs, None, None, False)\n> > > -        gains = np.reshape(gains, (-1, 3))\n> > > +        ct_curve, transverse_pos, transverse_neg = awb(imgs, None, None, False)\n> > > +        ct_curve = np.reshape(ct_curve, (-1, 3))\n> > > +        gains = [{\n> > > +            'ct': int(v[0]),\n> > > +            'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> > > +        } for v in ct_curve]\n> > > +\n> > > +        return {'colourGains': gains,\n> > > +                'transversePos': transverse_pos,\n> > > +                'transverseNeg': transverse_neg}\n> > >  \n> > > -        return [{\n> > > -                    'ct': int(v[0]),\n> > > -                    'gains': [float(1.0 / v[1]), float(1.0 / v[2])]\n> > > -                } for v in gains]\n> > > diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > > index 0c95843b83d3..d562d26eb8cc 100644\n> > > --- a/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > > +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py\n> > > @@ -6,9 +6,6 @@\n> > >  \n> > >  from .awb import AWB\n> > >  \n> > > -import libtuning as lt\n> > > -\n> > > -\n> > >  class AWBRkISP1(AWB):\n> > >      hr_name = 'AWB (RkISP1)'\n> > >      out_name = 'Awb'\n> > > @@ -20,8 +17,20 @@ class AWBRkISP1(AWB):\n> > >          return True\n> > >  \n> > >      def process(self, config: dict, images: list, outputs: dict) -> dict:\n> > > -        output = {}\n> > > -\n> > > -        output['colourGains'] = self.do_calculation(images)\n> > > +        if not 'awb' in config['general']:\n> > > +            raise ValueError('AWB configuration missing')\n> > > +        awb_config = config['general']['awb']\n> > > +        algorithm = awb_config['algorithm']\n> > > +\n> > > +        output = {'algorithm': algorithm}\n> > > +        data = self.do_calculation(images)\n> > > +        if algorithm == 'grey':\n> > > +            output['colourGains'] = data['colourGains']\n> > \n> > How come there's no output.update(data) on this code path ? (I don't\n> > know what it does yet, just noticing that it's only on one path).\n> \n> Arguably in the tuning code there is room for improvement :-). Reason is\n> that in the grey world case, we only need the colourGains in the tuning\n> file, in the bayes case we need all the results, so I just did\n> output.update(data) without manually stating every key.\n> \n> > \n> > Is there any argument to output the colourGains for greyworld as well as\n> > bayes to the same file ? or is Manual ColourTemperature handled\n> > distinctly with bayes (I presume it just overrides whatever the bayes\n> > would have predicted to be the colour temperature)\n> > \n> \n> I'm not sure if I completely understand what you mean here. colourGains\n> are needed for both cases (grey and bayes). But bayes needs the rest.\n> Would you prefer the following code?\n> \n> if algorithm == 'grey':\n>     output['colourGains'] = data['colourGains']\n> elif algorithm == 'bayes':\n>     output['AwbMode'] = awb_config['AwbMode']\n>     output['priors'] = awb_config['priors']\n>     output['colourGains'] = data['colourGains']\n>     output['transversePos'] = data['transversePos']\n>     output['transverseNeg'] = data['transverseNeg']\n\nAha, thanks I hadn't actually realsed that output.update(data) was just\nsimplifying the transverseNeg parts..\n\nI guess my point before was ... why not output it all if we've\ncalculated it. In AWB case, there's not a lot of 'cost' to storing this\ndata, but I can imagine in LSC or other algorithms the data might be\nmore costly if it's not used.\n\nBut ultimately - as long as the data is stored to be available when it's\nneeded I'm happy ;-)\n\n\nBut theres nothing here that would block merging so:\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> else:\n> ...\n> \n> \n> Best regards,\n> Stefan\n> \n> > \n> > > +        elif algorithm == 'bayes':\n> > > +            output['AwbMode'] = awb_config['AwbMode']\n> > > +            output['priors'] = awb_config['priors']\n> > > +            output.update(data)\n> > > +        else:\n> > > +            raise ValueError(f\"Unknown AWB algorithm {output['algorithm']}\")\n> > >  \n> > >          return output\n> > > -- \n> > > 2.43.0\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 79B25BE175\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 20 Feb 2025 12:02:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5E5B26869B;\n\tThu, 20 Feb 2025 13:02:20 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 41B986032B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 20 Feb 2025 13:02:18 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6C72E74C;\n\tThu, 20 Feb 2025 13:00:54 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"rAafkJjX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1740052854;\n\tbh=+MDeVUvgwDump5L5UDraxpnzFPIAYIv7vfkXY+509qo=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=rAafkJjXll9v1SH4ecSbg+0WgpNWttJIdTsmpNCiLaIzaX07Z7C4u4JREmGN9sKS/\n\tr4iOG+9FeJpTWi7R5DLGZbaJiG4naCfeuItVagzKo/IK+Ul2sbSkhfWQl+wyl7x/Ux\n\tFHOQ4W5MnyDEy4GyOSiw8G6k7Qm6RRcq6rKmI6vs=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<4njef35wyqt6qz2oul4yjg62ewedeebq6l5tksbgby5f3azzlh@wlzmlh6z62ql>","References":"<20250123114204.79321-1-stefan.klug@ideasonboard.com>\n\t<20250123114204.79321-9-stefan.klug@ideasonboard.com>\n\t<173962465086.4068558.6433182700528765410@ping.linuxembedded.co.uk>\n\t<4njef35wyqt6qz2oul4yjg62ewedeebq6l5tksbgby5f3azzlh@wlzmlh6z62ql>","Subject":"Re: [PATCH v2 08/17] libtuning: module: awb: Add bayes AWB support","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tPaul Elder <paul.elder@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>","Date":"Thu, 20 Feb 2025 12:02:15 +0000","Message-ID":"<174005293535.3771432.1558519353475570810@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]