[{"id":30593,"web_url":"https://patchwork.libcamera.org/comment/30593/","msgid":"<172286565455.1687952.12334046698958624071@ping.linuxembedded.co.uk>","date":"2024-08-05T13:47:34","subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2024-08-05 13:05:05)\n> Modify the awb function that was copied from the Raspberry Pi tuning\n> scripts in a way that it can easily be called from the libtuning code.\n> In essence the logging was replaced by calls to a python logger and the\n> need for the Cam object was removed by providing a list of images to the\n> function.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> ---\n>  utils/tuning/libtuning/ctt_awb.py | 55 ++++++++++++++++---------------\n>  1 file changed, 28 insertions(+), 27 deletions(-)\n> \n> diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py\n> index abf22321a0ea..73a1bc1a840c 100644\n> --- a/utils/tuning/libtuning/ctt_awb.py\n> +++ b/utils/tuning/libtuning/ctt_awb.py\n> @@ -4,6 +4,8 @@\n>  #\n>  # camera tuning tool for AWB\n>  \n> +import logging\n> +\n>  import matplotlib.pyplot as plt\n>  from bisect import bisect_left\n>  from scipy.optimize import fmin\n> @@ -11,12 +13,12 @@ import numpy as np\n>  \n>  from .image import Image\n>  \n> +logger = logging.getLogger(__name__)\n>  \n>  \"\"\"\n>  obtain piecewise linear approximation for colour curve\n>  \"\"\"\n> -def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> -    imgs = Cam.imgs\n\nDoes this break any other code? Or was this just a module that had been\n'copied/imported' and not yet used?\n\n\n\n> +def awb(imgs, cal_cr_list, cal_cb_list, plot):\n>      \"\"\"\n>      condense alsc calibration tables into one dictionary\n>      \"\"\"\n> @@ -39,7 +41,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>      rb_raw = []\n>      rbs_hat = []\n>      for Img in imgs:\n> -        Cam.log += '\\nProcessing '+Img.name\n> +        logger.info(f'Processing {Img.name}')\n>          \"\"\"\n>          get greyscale patches with alsc applied if alsc enabled.\n>          Note: if alsc is disabled then colour_cals will be set to None and the\n> @@ -51,7 +53,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>          \"\"\"\n>          r_g = np.mean(r_patchs/g_patchs)\n>          b_g = np.mean(b_patchs/g_patchs)\n> -        Cam.log += '\\n       r : {:.4f}       b : {:.4f}'.format(r_g, b_g)\n> +        logger.info('       r : {:.4f}       b : {:.4f}'.format(r_g, b_g))\n>          \"\"\"\n>          The curve tends to be better behaved in so-called hatspace.\n>          R, B, G represent the individual channels. The colour curve is plotted in\n> @@ -74,12 +76,11 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>          \"\"\"\n>          r_g_hat = r_g/(1+r_g+b_g)\n>          b_g_hat = b_g/(1+r_g+b_g)\n> -        Cam.log += '\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat)\n> -        rbs_hat.append((r_g_hat, b_g_hat, Img.col))\n> +        logger.info('\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat))\n> +        rbs_hat.append((r_g_hat, b_g_hat, Img.color))\n>          rb_raw.append((r_g, b_g))\n> -        Cam.log += '\\n'\n>  \n> -    Cam.log += '\\nFinished processing images'\n> +    logger.info('Finished processing images')\n>      \"\"\"\n>      sort all lits simultaneously by r_hat\n>      \"\"\"\n> @@ -95,7 +96,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>      fit quadratic fit to r_g hat and b_g_hat\n>      \"\"\"\n>      a, b, c = np.polyfit(rbs_hat[0], rbs_hat[1], 2)\n> -    Cam.log += '\\nFit quadratic curve in hatspace'\n> +    logger.info('Fit quadratic curve in hatspace')\n>      \"\"\"\n>      the algorithm now approximates the shortest distance from each point to the\n>      curve in dehatspace. Since the fit is done in hatspace, it is easier to\n> @@ -151,14 +152,14 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>          if (x+y) > (rr+bb):\n>              dist *= -1\n>          dists.append(dist)\n> -    Cam.log += '\\nFound closest point on fit line to each point in dehatspace'\n> +    logger.info('Found closest point on fit line to each point in dehatspace')\n>      \"\"\"\n>      calculate wiggle factors in awb. 10% added since this is an upper bound\n>      \"\"\"\n>      transverse_neg = - np.min(dists) * 1.1\n>      transverse_pos = np.max(dists) * 1.1\n> -    Cam.log += '\\nTransverse pos : {:.5f}'.format(transverse_pos)\n> -    Cam.log += '\\nTransverse neg : {:.5f}'.format(transverse_neg)\n> +    logger.info('Transverse pos : {:.5f}'.format(transverse_pos))\n> +    logger.info('Transverse neg : {:.5f}'.format(transverse_neg))\n>      \"\"\"\n>      set minimum transverse wiggles to 0.1 .\n>      Wiggle factors dictate how far off of the curve the algorithm searches. 0.1\n> @@ -167,10 +168,10 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>      \"\"\"\n>      if transverse_pos < 0.01:\n>          transverse_pos = 0.01\n> -        Cam.log += '\\nForced transverse pos to 0.01'\n> +        logger.info('Forced transverse pos to 0.01')\n>      if transverse_neg < 0.01:\n>          transverse_neg = 0.01\n> -        Cam.log += '\\nForced transverse neg to 0.01'\n> +        logger.info('Forced transverse neg to 0.01')\n>  \n>      \"\"\"\n>      generate new b_hat values at each r_hat according to fit\n> @@ -202,25 +203,25 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>      i = len(c_fit) - 1\n>      while i > 0:\n>          if c_fit[i] > c_fit[i-1]:\n> -            Cam.log += '\\nColour temperature increase found\\n'\n> -            Cam.log += '{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1])\n> -            Cam.log += '{} K at r = {}'.format(c_fit[i], r_fit[i])\n> +            logger.info('Colour temperature increase found')\n> +            logger.info('{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1]))\n> +            logger.info('{} K at r = {}'.format(c_fit[i], r_fit[i]))\n>              \"\"\"\n>              if colour temperature increases then discard point furthest from\n>              the transformed fit (dehatspace)\n>              \"\"\"\n>              error_1 = abs(dists[i-1])\n>              error_2 = abs(dists[i])\n> -            Cam.log += '\\nDistances from fit:\\n'\n> -            Cam.log += '{} K : {:.5f} , '.format(c_fit[i], error_1)\n> -            Cam.log += '{} K : {:.5f}'.format(c_fit[i-1], error_2)\n> +            logger.info('Distances from fit:')\n> +            logger.info('{} K : {:.5f} , '.format(c_fit[i], error_1))\n> +            logger.info('{} K : {:.5f}'.format(c_fit[i-1], error_2))\n>              \"\"\"\n>              find bad index\n>              note that in python false = 0 and true = 1\n>              \"\"\"\n>              bad = i - (error_1 < error_2)\n> -            Cam.log += '\\nPoint at {} K deleted as '.format(c_fit[bad])\n> -            Cam.log += 'it is furthest from fit'\n> +            logger.info('Point at {} K deleted as '.format(c_fit[bad]))\n> +            logger.info('it is furthest from fit')\n>              \"\"\"\n>              delete bad point\n>              \"\"\"\n> @@ -239,12 +240,12 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n>      return formatted ct curve, ordered by increasing colour temperature\n>      \"\"\"\n>      ct_curve = list(np.array(list(zip(b_fit, r_fit, c_fit))).flatten())[::-1]\n> -    Cam.log += '\\nFinal CT curve:'\n> +    logger.info('Final CT curve:')\n>      for i in range(len(ct_curve)//3):\n>          j = 3*i\n> -        Cam.log += '\\n  ct: {}  '.format(ct_curve[j])\n> -        Cam.log += '  r: {}  '.format(ct_curve[j+1])\n> -        Cam.log += '  b: {}  '.format(ct_curve[j+2])\n> +        logger.info('  ct: {}  '.format(ct_curve[j]))\n> +        logger.info('  r: {}  '.format(ct_curve[j+1]))\n> +        logger.info('  b: {}  '.format(ct_curve[j+2]))\n>  \n>      \"\"\"\n>      plotting code for debug\n> @@ -303,7 +304,7 @@ def get_alsc_patches(Img, colour_cals, grey=True):\n>      \"\"\"\n>      if grey:\n>          cen_coords = Img.cen_coords[3::4]\n> -        col = Img.col\n> +        col = Img.color\n>          patches = [np.array(Img.patches[i]) for i in Img.order]\n>          r_patchs = patches[0][3::4] - Img.blacklevel_16\n>          b_patchs = patches[3][3::4] - Img.blacklevel_16\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 7F293C323E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  5 Aug 2024 13:47:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 38A4F63382;\n\tMon,  5 Aug 2024 15:47:39 +0200 (CEST)","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 BA53963369\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  5 Aug 2024 15:47:37 +0200 (CEST)","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 585A618D;\n\tMon,  5 Aug 2024 15:46:46 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"j2RWFFRb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722865606;\n\tbh=fNECRMNZwlD89w1s3hgRXkrSJAMHHsML/ql3IXS1FWk=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=j2RWFFRbc5/ndvdoS8UMVAf7qQEzBU0KZCo9ZLMoNHDSLkkkOY2TmSI+ldnQ87kBD\n\tEq+v2fn8Iaq2685tcDWgiDbBblIh65I/BwUbT5og+PE3EvTxkDrypzgylkMWaemIES\n\t9Q6zRRHnLOfrY3q7ixJzZMHaHqNlXkgRL6dX3clM=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20240805120522.1613342-5-stefan.klug@ideasonboard.com>","References":"<20240805120522.1613342-1-stefan.klug@ideasonboard.com>\n\t<20240805120522.1613342-5-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"David Plowman <david.plowman@raspberrypi.com>,\n\tStefan Klug <stefan.klug@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 05 Aug 2024 14:47:34 +0100","Message-ID":"<172286565455.1687952.12334046698958624071@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":30608,"web_url":"https://patchwork.libcamera.org/comment/30608/","msgid":"<ma2at2vk6gxwbn67xzmwsqqh5e2mqada5eqdippgfzjpmprhu2@sfk4dohr6vzo>","date":"2024-08-06T06:41:52","subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Kieran,\n\nThanks for the review.\n\nOn Mon, Aug 05, 2024 at 02:47:34PM +0100, Kieran Bingham wrote:\n> Quoting Stefan Klug (2024-08-05 13:05:05)\n> > Modify the awb function that was copied from the Raspberry Pi tuning\n> > scripts in a way that it can easily be called from the libtuning code.\n> > In essence the logging was replaced by calls to a python logger and the\n> > need for the Cam object was removed by providing a list of images to the\n> > function.\n> > \n> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > ---\n> >  utils/tuning/libtuning/ctt_awb.py | 55 ++++++++++++++++---------------\n> >  1 file changed, 28 insertions(+), 27 deletions(-)\n> > \n> > diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py\n> > index abf22321a0ea..73a1bc1a840c 100644\n> > --- a/utils/tuning/libtuning/ctt_awb.py\n> > +++ b/utils/tuning/libtuning/ctt_awb.py\n> > @@ -4,6 +4,8 @@\n> >  #\n> >  # camera tuning tool for AWB\n> >  \n> > +import logging\n> > +\n> >  import matplotlib.pyplot as plt\n> >  from bisect import bisect_left\n> >  from scipy.optimize import fmin\n> > @@ -11,12 +13,12 @@ import numpy as np\n> >  \n> >  from .image import Image\n> >  \n> > +logger = logging.getLogger(__name__)\n> >  \n> >  \"\"\"\n> >  obtain piecewise linear approximation for colour curve\n> >  \"\"\"\n> > -def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > -    imgs = Cam.imgs\n> \n> Does this break any other code? Or was this just a module that had been\n> 'copied/imported' and not yet used?\n\nYes the files were copied verbatim. Only the parts needed were adjusted\nto work. Might well be that this one is the last one missing.\n\n> \n> \n> \n> > +def awb(imgs, cal_cr_list, cal_cb_list, plot):\n> >      \"\"\"\n> >      condense alsc calibration tables into one dictionary\n> >      \"\"\"\n> > @@ -39,7 +41,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >      rb_raw = []\n> >      rbs_hat = []\n> >      for Img in imgs:\n> > -        Cam.log += '\\nProcessing '+Img.name\n> > +        logger.info(f'Processing {Img.name}')\n> >          \"\"\"\n> >          get greyscale patches with alsc applied if alsc enabled.\n> >          Note: if alsc is disabled then colour_cals will be set to None and the\n> > @@ -51,7 +53,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >          \"\"\"\n> >          r_g = np.mean(r_patchs/g_patchs)\n> >          b_g = np.mean(b_patchs/g_patchs)\n> > -        Cam.log += '\\n       r : {:.4f}       b : {:.4f}'.format(r_g, b_g)\n> > +        logger.info('       r : {:.4f}       b : {:.4f}'.format(r_g, b_g))\n> >          \"\"\"\n> >          The curve tends to be better behaved in so-called hatspace.\n> >          R, B, G represent the individual channels. The colour curve is plotted in\n> > @@ -74,12 +76,11 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >          \"\"\"\n> >          r_g_hat = r_g/(1+r_g+b_g)\n> >          b_g_hat = b_g/(1+r_g+b_g)\n> > -        Cam.log += '\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat)\n> > -        rbs_hat.append((r_g_hat, b_g_hat, Img.col))\n> > +        logger.info('\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat))\n> > +        rbs_hat.append((r_g_hat, b_g_hat, Img.color))\n> >          rb_raw.append((r_g, b_g))\n> > -        Cam.log += '\\n'\n> >  \n> > -    Cam.log += '\\nFinished processing images'\n> > +    logger.info('Finished processing images')\n> >      \"\"\"\n> >      sort all lits simultaneously by r_hat\n> >      \"\"\"\n> > @@ -95,7 +96,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >      fit quadratic fit to r_g hat and b_g_hat\n> >      \"\"\"\n> >      a, b, c = np.polyfit(rbs_hat[0], rbs_hat[1], 2)\n> > -    Cam.log += '\\nFit quadratic curve in hatspace'\n> > +    logger.info('Fit quadratic curve in hatspace')\n> >      \"\"\"\n> >      the algorithm now approximates the shortest distance from each point to the\n> >      curve in dehatspace. Since the fit is done in hatspace, it is easier to\n> > @@ -151,14 +152,14 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >          if (x+y) > (rr+bb):\n> >              dist *= -1\n> >          dists.append(dist)\n> > -    Cam.log += '\\nFound closest point on fit line to each point in dehatspace'\n> > +    logger.info('Found closest point on fit line to each point in dehatspace')\n> >      \"\"\"\n> >      calculate wiggle factors in awb. 10% added since this is an upper bound\n> >      \"\"\"\n> >      transverse_neg = - np.min(dists) * 1.1\n> >      transverse_pos = np.max(dists) * 1.1\n> > -    Cam.log += '\\nTransverse pos : {:.5f}'.format(transverse_pos)\n> > -    Cam.log += '\\nTransverse neg : {:.5f}'.format(transverse_neg)\n> > +    logger.info('Transverse pos : {:.5f}'.format(transverse_pos))\n> > +    logger.info('Transverse neg : {:.5f}'.format(transverse_neg))\n> >      \"\"\"\n> >      set minimum transverse wiggles to 0.1 .\n> >      Wiggle factors dictate how far off of the curve the algorithm searches. 0.1\n> > @@ -167,10 +168,10 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >      \"\"\"\n> >      if transverse_pos < 0.01:\n> >          transverse_pos = 0.01\n> > -        Cam.log += '\\nForced transverse pos to 0.01'\n> > +        logger.info('Forced transverse pos to 0.01')\n> >      if transverse_neg < 0.01:\n> >          transverse_neg = 0.01\n> > -        Cam.log += '\\nForced transverse neg to 0.01'\n> > +        logger.info('Forced transverse neg to 0.01')\n> >  \n> >      \"\"\"\n> >      generate new b_hat values at each r_hat according to fit\n> > @@ -202,25 +203,25 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >      i = len(c_fit) - 1\n> >      while i > 0:\n> >          if c_fit[i] > c_fit[i-1]:\n> > -            Cam.log += '\\nColour temperature increase found\\n'\n> > -            Cam.log += '{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1])\n> > -            Cam.log += '{} K at r = {}'.format(c_fit[i], r_fit[i])\n> > +            logger.info('Colour temperature increase found')\n> > +            logger.info('{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1]))\n> > +            logger.info('{} K at r = {}'.format(c_fit[i], r_fit[i]))\n> >              \"\"\"\n> >              if colour temperature increases then discard point furthest from\n> >              the transformed fit (dehatspace)\n> >              \"\"\"\n> >              error_1 = abs(dists[i-1])\n> >              error_2 = abs(dists[i])\n> > -            Cam.log += '\\nDistances from fit:\\n'\n> > -            Cam.log += '{} K : {:.5f} , '.format(c_fit[i], error_1)\n> > -            Cam.log += '{} K : {:.5f}'.format(c_fit[i-1], error_2)\n> > +            logger.info('Distances from fit:')\n> > +            logger.info('{} K : {:.5f} , '.format(c_fit[i], error_1))\n> > +            logger.info('{} K : {:.5f}'.format(c_fit[i-1], error_2))\n> >              \"\"\"\n> >              find bad index\n> >              note that in python false = 0 and true = 1\n> >              \"\"\"\n> >              bad = i - (error_1 < error_2)\n> > -            Cam.log += '\\nPoint at {} K deleted as '.format(c_fit[bad])\n> > -            Cam.log += 'it is furthest from fit'\n> > +            logger.info('Point at {} K deleted as '.format(c_fit[bad]))\n> > +            logger.info('it is furthest from fit')\n> >              \"\"\"\n> >              delete bad point\n> >              \"\"\"\n> > @@ -239,12 +240,12 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> >      return formatted ct curve, ordered by increasing colour temperature\n> >      \"\"\"\n> >      ct_curve = list(np.array(list(zip(b_fit, r_fit, c_fit))).flatten())[::-1]\n> > -    Cam.log += '\\nFinal CT curve:'\n> > +    logger.info('Final CT curve:')\n> >      for i in range(len(ct_curve)//3):\n> >          j = 3*i\n> > -        Cam.log += '\\n  ct: {}  '.format(ct_curve[j])\n> > -        Cam.log += '  r: {}  '.format(ct_curve[j+1])\n> > -        Cam.log += '  b: {}  '.format(ct_curve[j+2])\n> > +        logger.info('  ct: {}  '.format(ct_curve[j]))\n> > +        logger.info('  r: {}  '.format(ct_curve[j+1]))\n> > +        logger.info('  b: {}  '.format(ct_curve[j+2]))\n> >  \n> >      \"\"\"\n> >      plotting code for debug\n> > @@ -303,7 +304,7 @@ def get_alsc_patches(Img, colour_cals, grey=True):\n> >      \"\"\"\n> >      if grey:\n> >          cen_coords = Img.cen_coords[3::4]\n> > -        col = Img.col\n> > +        col = Img.color\n> >          patches = [np.array(Img.patches[i]) for i in Img.order]\n> >          r_patchs = patches[0][3::4] - Img.blacklevel_16\n> >          b_patchs = patches[3][3::4] - Img.blacklevel_16\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 94246BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  6 Aug 2024 06:41:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E728363393;\n\tTue,  6 Aug 2024 08:41:57 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 557E06337E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  6 Aug 2024 08:41:56 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:7a68:2b6f:8265:aa72])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 517392C5;\n\tTue,  6 Aug 2024 08:41:04 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"A7byy1og\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722926464;\n\tbh=VBk3Ba50cevM0JC1bTU2AqBy7YAdzhj9yM40kWQoXvM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=A7byy1og+p2sHSUDclI1WW2/YU/dVwF8jVGS++8V1FdMdkQDBRsXskAxpApkdm/2C\n\teILBkBwT6/0/080bXyODBn6ZAUlHMVlDNMlrEGplNYX5evUnfPYTC5DJ9BaATwIqS2\n\tqd5lHKhS+xKfBjfA7MPMGfMcWpKfVz6LUnx/laHU=","Date":"Tue, 6 Aug 2024 08:41:52 +0200","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tDavid Plowman <david.plowman@raspberrypi.com>","Subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","Message-ID":"<ma2at2vk6gxwbn67xzmwsqqh5e2mqada5eqdippgfzjpmprhu2@sfk4dohr6vzo>","References":"<20240805120522.1613342-1-stefan.klug@ideasonboard.com>\n\t<20240805120522.1613342-5-stefan.klug@ideasonboard.com>\n\t<172286565455.1687952.12334046698958624071@ping.linuxembedded.co.uk>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<172286565455.1687952.12334046698958624071@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":30620,"web_url":"https://patchwork.libcamera.org/comment/30620/","msgid":"<172293453976.1687952.8194740688555083052@ping.linuxembedded.co.uk>","date":"2024-08-06T08:55:39","subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2024-08-06 07:41:52)\n> Hi Kieran,\n> \n> Thanks for the review.\n> \n> On Mon, Aug 05, 2024 at 02:47:34PM +0100, Kieran Bingham wrote:\n> > Quoting Stefan Klug (2024-08-05 13:05:05)\n> > > Modify the awb function that was copied from the Raspberry Pi tuning\n> > > scripts in a way that it can easily be called from the libtuning code.\n> > > In essence the logging was replaced by calls to a python logger and the\n> > > need for the Cam object was removed by providing a list of images to the\n> > > function.\n> > > \n> > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > > ---\n> > >  utils/tuning/libtuning/ctt_awb.py | 55 ++++++++++++++++---------------\n> > >  1 file changed, 28 insertions(+), 27 deletions(-)\n> > > \n> > > diff --git a/utils/tuning/libtuning/ctt_awb.py b/utils/tuning/libtuning/ctt_awb.py\n> > > index abf22321a0ea..73a1bc1a840c 100644\n> > > --- a/utils/tuning/libtuning/ctt_awb.py\n> > > +++ b/utils/tuning/libtuning/ctt_awb.py\n> > > @@ -4,6 +4,8 @@\n> > >  #\n> > >  # camera tuning tool for AWB\n> > >  \n> > > +import logging\n> > > +\n> > >  import matplotlib.pyplot as plt\n> > >  from bisect import bisect_left\n> > >  from scipy.optimize import fmin\n> > > @@ -11,12 +13,12 @@ import numpy as np\n> > >  \n> > >  from .image import Image\n> > >  \n> > > +logger = logging.getLogger(__name__)\n> > >  \n> > >  \"\"\"\n> > >  obtain piecewise linear approximation for colour curve\n> > >  \"\"\"\n> > > -def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > > -    imgs = Cam.imgs\n> > \n> > Does this break any other code? Or was this just a module that had been\n> > 'copied/imported' and not yet used?\n> \n> Yes the files were copied verbatim. Only the parts needed were adjusted\n> to work. Might well be that this one is the last one missing.\n\nOk, so if it doesn't break bisectability: (which ... doesn't quite apply\nin the same way for the tuning tool which doesn't get built, but could\nbe 'used'?)\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\n\n> \n> > \n> > \n> > \n> > > +def awb(imgs, cal_cr_list, cal_cb_list, plot):\n> > >      \"\"\"\n> > >      condense alsc calibration tables into one dictionary\n> > >      \"\"\"\n> > > @@ -39,7 +41,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >      rb_raw = []\n> > >      rbs_hat = []\n> > >      for Img in imgs:\n> > > -        Cam.log += '\\nProcessing '+Img.name\n> > > +        logger.info(f'Processing {Img.name}')\n> > >          \"\"\"\n> > >          get greyscale patches with alsc applied if alsc enabled.\n> > >          Note: if alsc is disabled then colour_cals will be set to None and the\n> > > @@ -51,7 +53,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >          \"\"\"\n> > >          r_g = np.mean(r_patchs/g_patchs)\n> > >          b_g = np.mean(b_patchs/g_patchs)\n> > > -        Cam.log += '\\n       r : {:.4f}       b : {:.4f}'.format(r_g, b_g)\n> > > +        logger.info('       r : {:.4f}       b : {:.4f}'.format(r_g, b_g))\n> > >          \"\"\"\n> > >          The curve tends to be better behaved in so-called hatspace.\n> > >          R, B, G represent the individual channels. The colour curve is plotted in\n> > > @@ -74,12 +76,11 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >          \"\"\"\n> > >          r_g_hat = r_g/(1+r_g+b_g)\n> > >          b_g_hat = b_g/(1+r_g+b_g)\n> > > -        Cam.log += '\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat)\n> > > -        rbs_hat.append((r_g_hat, b_g_hat, Img.col))\n> > > +        logger.info('\\n   r_hat : {:.4f}   b_hat : {:.4f}'.format(r_g_hat, b_g_hat))\n> > > +        rbs_hat.append((r_g_hat, b_g_hat, Img.color))\n> > >          rb_raw.append((r_g, b_g))\n> > > -        Cam.log += '\\n'\n> > >  \n> > > -    Cam.log += '\\nFinished processing images'\n> > > +    logger.info('Finished processing images')\n> > >      \"\"\"\n> > >      sort all lits simultaneously by r_hat\n> > >      \"\"\"\n> > > @@ -95,7 +96,7 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >      fit quadratic fit to r_g hat and b_g_hat\n> > >      \"\"\"\n> > >      a, b, c = np.polyfit(rbs_hat[0], rbs_hat[1], 2)\n> > > -    Cam.log += '\\nFit quadratic curve in hatspace'\n> > > +    logger.info('Fit quadratic curve in hatspace')\n> > >      \"\"\"\n> > >      the algorithm now approximates the shortest distance from each point to the\n> > >      curve in dehatspace. Since the fit is done in hatspace, it is easier to\n> > > @@ -151,14 +152,14 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >          if (x+y) > (rr+bb):\n> > >              dist *= -1\n> > >          dists.append(dist)\n> > > -    Cam.log += '\\nFound closest point on fit line to each point in dehatspace'\n> > > +    logger.info('Found closest point on fit line to each point in dehatspace')\n> > >      \"\"\"\n> > >      calculate wiggle factors in awb. 10% added since this is an upper bound\n> > >      \"\"\"\n> > >      transverse_neg = - np.min(dists) * 1.1\n> > >      transverse_pos = np.max(dists) * 1.1\n> > > -    Cam.log += '\\nTransverse pos : {:.5f}'.format(transverse_pos)\n> > > -    Cam.log += '\\nTransverse neg : {:.5f}'.format(transverse_neg)\n> > > +    logger.info('Transverse pos : {:.5f}'.format(transverse_pos))\n> > > +    logger.info('Transverse neg : {:.5f}'.format(transverse_neg))\n> > >      \"\"\"\n> > >      set minimum transverse wiggles to 0.1 .\n> > >      Wiggle factors dictate how far off of the curve the algorithm searches. 0.1\n> > > @@ -167,10 +168,10 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >      \"\"\"\n> > >      if transverse_pos < 0.01:\n> > >          transverse_pos = 0.01\n> > > -        Cam.log += '\\nForced transverse pos to 0.01'\n> > > +        logger.info('Forced transverse pos to 0.01')\n> > >      if transverse_neg < 0.01:\n> > >          transverse_neg = 0.01\n> > > -        Cam.log += '\\nForced transverse neg to 0.01'\n> > > +        logger.info('Forced transverse neg to 0.01')\n> > >  \n> > >      \"\"\"\n> > >      generate new b_hat values at each r_hat according to fit\n> > > @@ -202,25 +203,25 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >      i = len(c_fit) - 1\n> > >      while i > 0:\n> > >          if c_fit[i] > c_fit[i-1]:\n> > > -            Cam.log += '\\nColour temperature increase found\\n'\n> > > -            Cam.log += '{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1])\n> > > -            Cam.log += '{} K at r = {}'.format(c_fit[i], r_fit[i])\n> > > +            logger.info('Colour temperature increase found')\n> > > +            logger.info('{} K at r = {} to '.format(c_fit[i-1], r_fit[i-1]))\n> > > +            logger.info('{} K at r = {}'.format(c_fit[i], r_fit[i]))\n> > >              \"\"\"\n> > >              if colour temperature increases then discard point furthest from\n> > >              the transformed fit (dehatspace)\n> > >              \"\"\"\n> > >              error_1 = abs(dists[i-1])\n> > >              error_2 = abs(dists[i])\n> > > -            Cam.log += '\\nDistances from fit:\\n'\n> > > -            Cam.log += '{} K : {:.5f} , '.format(c_fit[i], error_1)\n> > > -            Cam.log += '{} K : {:.5f}'.format(c_fit[i-1], error_2)\n> > > +            logger.info('Distances from fit:')\n> > > +            logger.info('{} K : {:.5f} , '.format(c_fit[i], error_1))\n> > > +            logger.info('{} K : {:.5f}'.format(c_fit[i-1], error_2))\n> > >              \"\"\"\n> > >              find bad index\n> > >              note that in python false = 0 and true = 1\n> > >              \"\"\"\n> > >              bad = i - (error_1 < error_2)\n> > > -            Cam.log += '\\nPoint at {} K deleted as '.format(c_fit[bad])\n> > > -            Cam.log += 'it is furthest from fit'\n> > > +            logger.info('Point at {} K deleted as '.format(c_fit[bad]))\n> > > +            logger.info('it is furthest from fit')\n> > >              \"\"\"\n> > >              delete bad point\n> > >              \"\"\"\n> > > @@ -239,12 +240,12 @@ def awb(Cam, cal_cr_list, cal_cb_list, plot):\n> > >      return formatted ct curve, ordered by increasing colour temperature\n> > >      \"\"\"\n> > >      ct_curve = list(np.array(list(zip(b_fit, r_fit, c_fit))).flatten())[::-1]\n> > > -    Cam.log += '\\nFinal CT curve:'\n> > > +    logger.info('Final CT curve:')\n> > >      for i in range(len(ct_curve)//3):\n> > >          j = 3*i\n> > > -        Cam.log += '\\n  ct: {}  '.format(ct_curve[j])\n> > > -        Cam.log += '  r: {}  '.format(ct_curve[j+1])\n> > > -        Cam.log += '  b: {}  '.format(ct_curve[j+2])\n> > > +        logger.info('  ct: {}  '.format(ct_curve[j]))\n> > > +        logger.info('  r: {}  '.format(ct_curve[j+1]))\n> > > +        logger.info('  b: {}  '.format(ct_curve[j+2]))\n> > >  \n> > >      \"\"\"\n> > >      plotting code for debug\n> > > @@ -303,7 +304,7 @@ def get_alsc_patches(Img, colour_cals, grey=True):\n> > >      \"\"\"\n> > >      if grey:\n> > >          cen_coords = Img.cen_coords[3::4]\n> > > -        col = Img.col\n> > > +        col = Img.color\n> > >          patches = [np.array(Img.patches[i]) for i in Img.order]\n> > >          r_patchs = patches[0][3::4] - Img.blacklevel_16\n> > >          b_patchs = patches[3][3::4] - Img.blacklevel_16\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 11DA8C323E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  6 Aug 2024 08:55:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AD89D63394;\n\tTue,  6 Aug 2024 10:55:45 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BD5D76337E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  6 Aug 2024 10:55:42 +0200 (CEST)","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 CDD894CD;\n\tTue,  6 Aug 2024 10:54:50 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"i03uV6fN\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722934490;\n\tbh=Z1vIoBCUivmyX47J6GhuIPtJDeiCWFk+S5Lw9fAN5mE=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=i03uV6fNQvCFdunrFHb02SsAjdtOJ3kAas2ytPEbxWDIbg+q+YwN5qVYHALu+Ul25\n\tCCJM/8lYKRiaOHVI4+yQ745UW4UQTCGHMzr/z5BlrfHN2/O0Uy4mafMhGJTMTUb1/3\n\tk6w5faW6Olvmwl1wP3OSBaVYgcF7bHG5Gm4hltvY=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<ma2at2vk6gxwbn67xzmwsqqh5e2mqada5eqdippgfzjpmprhu2@sfk4dohr6vzo>","References":"<20240805120522.1613342-1-stefan.klug@ideasonboard.com>\n\t<20240805120522.1613342-5-stefan.klug@ideasonboard.com>\n\t<172286565455.1687952.12334046698958624071@ping.linuxembedded.co.uk>\n\t<ma2at2vk6gxwbn67xzmwsqqh5e2mqada5eqdippgfzjpmprhu2@sfk4dohr6vzo>","Subject":"Re: [PATCH v1 4/6] libtuning: Modify ctt_awb.awb() so that it can\n\trun in our context","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tDavid Plowman <david.plowman@raspberrypi.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>","Date":"Tue, 06 Aug 2024 09:55:39 +0100","Message-ID":"<172293453976.1687952.8194740688555083052@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>"}}]