[{"id":19933,"web_url":"https://patchwork.libcamera.org/comment/19933/","msgid":"<20210928153950.pnujxpahztrcfvu2@ideasonboard.com>","date":"2021-09-28T15:39:50","subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"On Thu, Sep 23, 2021 at 10:16:20AM +0200, Jean-Michel Hautbois wrote:\n> The algorithm uses the statistics of a cell only if there is not too\n> much saturated pixels in it. The grey world algorithm works fine when\n> there are a limited number of outliers.\n> Consider a valid zone to be at least 80% of unsaturated cells in it.\n> This value could very well be configurable, and make the algorithm more\n> or less tolerant.\n> \n> While at it, implement it in a configure() call as it will not change\n> during execution, and cache the cellsPerZone values.\n> \n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> ---\n>  src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++---------\n>  src/ipa/ipu3/algorithms/awb.h   |  5 +++++\n>  2 files changed, 28 insertions(+), 9 deletions(-)\n> \n> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n> index 51a38d05..800d023c 100644\n> --- a/src/ipa/ipu3/algorithms/awb.cpp\n> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n> @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {\n>  \n>  LOG_DEFINE_CATEGORY(IPU3Awb)\n>  \n> -static constexpr uint32_t kMinZonesCounted = 16;\n>  static constexpr uint32_t kMinGreenLevelInZone = 32;\n>  \n>  /**\n> @@ -169,6 +168,24 @@ Awb::Awb()\n>  \n>  Awb::~Awb() = default;\n>  \n> +int Awb::configure(IPAContext &context,\n> +\t\t   [[maybe_unused]] const IPAConfigInfo &configInfo)\n> +{\n> +\tconst ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;\n> +\n> +\tcellsPerZoneX_ = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> +\tcellsPerZoneY_ = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> +\n> +\t/*\n> +\t * Configure the minimum proportion of cells counted within a zone\n> +\t * for it to be relevant for the grey world algorithm.\n> +\t * \\todo This proportion could be configured.\n> +\t */\n> +\tcellsPerZoneThreshold_ = (cellsPerZoneX_ * cellsPerZoneY_) * 80 / 100;\n> +\n> +\treturn 0;\n> +}\n> +\n>  /**\n>   * The function estimates the correlated color temperature using\n>   * from RGB color space input.\n> @@ -205,7 +222,7 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>  \tfor (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {\n>  \t\tRGB zone;\n>  \t\tdouble counted = awbStats_[i].counted;\n> -\t\tif (counted >= kMinZonesCounted) {\n> +\t\tif (counted >= cellsPerZoneThreshold_) {\n>  \t\t\tzone.G = awbStats_[i].sum.green / counted;\n>  \t\t\tif (zone.G >= kMinGreenLevelInZone) {\n>  \t\t\t\tzone.R = awbStats_[i].sum.red / counted;\n> @@ -220,19 +237,16 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>  void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,\n>  \t\t\t   const ipu3_uapi_grid_config &grid)\n>  {\n> -\tuint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> -\tuint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> -\n>  \t/*\n>  \t * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is\n>  \t * (grid.width x grid.height).\n>  \t */\n> -\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {\n> -\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {\n> +\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n> +\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n>  \t\t\tuint32_t cellPosition = (cellY * grid.width + cellX)\n>  \t\t\t\t\t      * sizeof(Ipu3AwbCell);\n> -\t\t\tuint32_t zoneX = cellX / cellsPerZoneX;\n> -\t\t\tuint32_t zoneY = cellY / cellsPerZoneY;\n> +\t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n> +\t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n>  \n>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n>  \n> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n> index 3385ebe7..681d8c2b 100644\n> --- a/src/ipa/ipu3/algorithms/awb.h\n> +++ b/src/ipa/ipu3/algorithms/awb.h\n> @@ -48,6 +48,7 @@ public:\n>  \tAwb();\n>  \t~Awb();\n>  \n> +\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n>  \tvoid prepare(IPAContext &context, ipu3_uapi_params *params) override;\n>  \tvoid process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;\n>  \n> @@ -85,6 +86,10 @@ private:\n>  \tstd::vector<RGB> zones_;\n>  \tAccumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];\n>  \tAwbStatus asyncResults_;\n> +\n> +\tuint32_t cellsPerZoneX_;\n> +\tuint32_t cellsPerZoneY_;\n> +\tuint32_t cellsPerZoneThreshold_;\n>  };\n>  \n>  } /* namespace ipa::ipu3::algorithms */\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 810A4C3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Sep 2021 15:39:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AD37A69191;\n\tTue, 28 Sep 2021 17:39:54 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CD4F369188\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Sep 2021 17:39:52 +0200 (CEST)","from ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 690963F1;\n\tTue, 28 Sep 2021 17:39:52 +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=\"d4k4wybk\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632843592;\n\tbh=LkZV2ArKRovaxOorIhPtXsesEW7L6zNXrE42g9/zpvM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=d4k4wybk8BtHhFMLuQYKSEKL4+KwgI8+CXG1VMDgH+LsTIdEmg3noC2JnWno5lrma\n\tE9e4+y8rW3RLPE7al1lOwWOtd5TALtt97MgXmJlN36iZudCnG+vPCjv+K4esB5DnES\n\t+EtDXPCa7hw5c6aEhLf3g+nRoPkkQdfISLIGqTFo=","Date":"Tue, 28 Sep 2021 16:39:50 +0100","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<20210928153950.pnujxpahztrcfvu2@ideasonboard.com>","References":"<20210923081625.60276-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19991,"web_url":"https://patchwork.libcamera.org/comment/19991/","msgid":"<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>","date":"2021-09-29T12:15:50","subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nThank you for the patch.\n\nOn Thu, Sep 23, 2021 at 10:16:20AM +0200, Jean-Michel Hautbois wrote:\n> The algorithm uses the statistics of a cell only if there is not too\n> much saturated pixels in it. The grey world algorithm works fine when\n> there are a limited number of outliers.\n> Consider a valid zone to be at least 80% of unsaturated cells in it.\n> This value could very well be configurable, and make the algorithm more\n> or less tolerant.\n> \n> While at it, implement it in a configure() call as it will not change\n> during execution, and cache the cellsPerZone values.\n> \n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> ---\n>  src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++---------\n>  src/ipa/ipu3/algorithms/awb.h   |  5 +++++\n>  2 files changed, 28 insertions(+), 9 deletions(-)\n> \n> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n> index 51a38d05..800d023c 100644\n> --- a/src/ipa/ipu3/algorithms/awb.cpp\n> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n> @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {\n>  \n>  LOG_DEFINE_CATEGORY(IPU3Awb)\n>  \n> -static constexpr uint32_t kMinZonesCounted = 16;\n>  static constexpr uint32_t kMinGreenLevelInZone = 32;\n>  \n>  /**\n> @@ -169,6 +168,24 @@ Awb::Awb()\n>  \n>  Awb::~Awb() = default;\n>  \n> +int Awb::configure(IPAContext &context,\n> +\t\t   [[maybe_unused]] const IPAConfigInfo &configInfo)\n> +{\n> +\tconst ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;\n> +\n> +\tcellsPerZoneX_ = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n\ns/round/std::round/\n\nas you're using cmath (with a small corresponding comment in the commit\nmessage).\n\n> +\tcellsPerZoneY_ = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> +\n> +\t/*\n> +\t * Configure the minimum proportion of cells counted within a zone\n> +\t * for it to be relevant for the grey world algorithm.\n> +\t * \\todo This proportion could be configured.\n> +\t */\n> +\tcellsPerZoneThreshold_ = (cellsPerZoneX_ * cellsPerZoneY_) * 80 / 100;\n\nNo need for parentheses.\n\nThe patch looks fine to me, so\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nThis however led me to notice that if the grid width isn't a multiple of\n16, we'll ignore some of the cells. If the grid width is 79, for\ninstance, 15 cells will be ignored. Would it be worth fixing that ?\n\n> +\n> +\treturn 0;\n> +}\n> +\n>  /**\n>   * The function estimates the correlated color temperature using\n>   * from RGB color space input.\n> @@ -205,7 +222,7 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>  \tfor (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {\n>  \t\tRGB zone;\n>  \t\tdouble counted = awbStats_[i].counted;\n> -\t\tif (counted >= kMinZonesCounted) {\n> +\t\tif (counted >= cellsPerZoneThreshold_) {\n>  \t\t\tzone.G = awbStats_[i].sum.green / counted;\n>  \t\t\tif (zone.G >= kMinGreenLevelInZone) {\n>  \t\t\t\tzone.R = awbStats_[i].sum.red / counted;\n> @@ -220,19 +237,16 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>  void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,\n>  \t\t\t   const ipu3_uapi_grid_config &grid)\n>  {\n> -\tuint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> -\tuint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> -\n>  \t/*\n>  \t * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is\n>  \t * (grid.width x grid.height).\n>  \t */\n> -\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {\n> -\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {\n> +\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n> +\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n>  \t\t\tuint32_t cellPosition = (cellY * grid.width + cellX)\n>  \t\t\t\t\t      * sizeof(Ipu3AwbCell);\n> -\t\t\tuint32_t zoneX = cellX / cellsPerZoneX;\n> -\t\t\tuint32_t zoneY = cellY / cellsPerZoneY;\n> +\t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n> +\t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n>  \n>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n>  \n> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n> index 3385ebe7..681d8c2b 100644\n> --- a/src/ipa/ipu3/algorithms/awb.h\n> +++ b/src/ipa/ipu3/algorithms/awb.h\n> @@ -48,6 +48,7 @@ public:\n>  \tAwb();\n>  \t~Awb();\n>  \n> +\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n>  \tvoid prepare(IPAContext &context, ipu3_uapi_params *params) override;\n>  \tvoid process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;\n>  \n> @@ -85,6 +86,10 @@ private:\n>  \tstd::vector<RGB> zones_;\n>  \tAccumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];\n>  \tAwbStatus asyncResults_;\n> +\n> +\tuint32_t cellsPerZoneX_;\n> +\tuint32_t cellsPerZoneY_;\n> +\tuint32_t cellsPerZoneThreshold_;\n>  };\n>  \n>  } /* namespace ipa::ipu3::algorithms */","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 666ABC3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Sep 2021 12:15:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DD856691AA;\n\tWed, 29 Sep 2021 14:15:53 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BBC4469185\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Sep 2021 14:15:52 +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 3A6023F0;\n\tWed, 29 Sep 2021 14:15:52 +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=\"P45mJmGV\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632917752;\n\tbh=K/S6n/msb1bGUtSv3LT14rboSH8L4oPPLgSGoSwpoQI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=P45mJmGVIqzxCkcgYwZdNHOi4ttQKyf+VgBUNuSbwafC5lcE7br8Oe2WuCFMXTjXj\n\tDn3jHxZ0M7vtN1HbL0IY+kzQLADfBwqc16G3cOGTFgRAGA8jTLrG9zPj75P94f7Mt3\n\tfbfxAvBYmXNfL3OuN9ou5kZtnXlntV3ELTjIK+Zo=","Date":"Wed, 29 Sep 2021 15:15:50 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>","References":"<20210923081625.60276-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19994,"web_url":"https://patchwork.libcamera.org/comment/19994/","msgid":"<dfdabd20-912e-d2a3-c255-8161b08293c8@ideasonboard.com>","date":"2021-09-29T12:32:00","subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 29/09/2021 14:15, Laurent Pinchart wrote:\n> Hi Jean-Michel,\n> \n> Thank you for the patch.\n> \n> On Thu, Sep 23, 2021 at 10:16:20AM +0200, Jean-Michel Hautbois wrote:\n>> The algorithm uses the statistics of a cell only if there is not too\n>> much saturated pixels in it. The grey world algorithm works fine when\n>> there are a limited number of outliers.\n>> Consider a valid zone to be at least 80% of unsaturated cells in it.\n>> This value could very well be configurable, and make the algorithm more\n>> or less tolerant.\n>>\n>> While at it, implement it in a configure() call as it will not change\n>> during execution, and cache the cellsPerZone values.\n>>\n>> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n>> ---\n>>  src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++---------\n>>  src/ipa/ipu3/algorithms/awb.h   |  5 +++++\n>>  2 files changed, 28 insertions(+), 9 deletions(-)\n>>\n>> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n>> index 51a38d05..800d023c 100644\n>> --- a/src/ipa/ipu3/algorithms/awb.cpp\n>> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n>> @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {\n>>  \n>>  LOG_DEFINE_CATEGORY(IPU3Awb)\n>>  \n>> -static constexpr uint32_t kMinZonesCounted = 16;\n>>  static constexpr uint32_t kMinGreenLevelInZone = 32;\n>>  \n>>  /**\n>> @@ -169,6 +168,24 @@ Awb::Awb()\n>>  \n>>  Awb::~Awb() = default;\n>>  \n>> +int Awb::configure(IPAContext &context,\n>> +\t\t   [[maybe_unused]] const IPAConfigInfo &configInfo)\n>> +{\n>> +\tconst ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;\n>> +\n>> +\tcellsPerZoneX_ = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> \n> s/round/std::round/\n> \n> as you're using cmath (with a small corresponding comment in the commit\n> message).\n\nOK :-).\n\n> \n>> +\tcellsPerZoneY_ = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n>> +\n>> +\t/*\n>> +\t * Configure the minimum proportion of cells counted within a zone\n>> +\t * for it to be relevant for the grey world algorithm.\n>> +\t * \\todo This proportion could be configured.\n>> +\t */\n>> +\tcellsPerZoneThreshold_ = (cellsPerZoneX_ * cellsPerZoneY_) * 80 / 100;\n> \n> No need for parentheses.\n> \n> The patch looks fine to me, so\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> This however led me to notice that if the grid width isn't a multiple of\n> 16, we'll ignore some of the cells. If the grid width is 79, for\n> instance, 15 cells will be ignored. Would it be worth fixing that ?\n\nWe could still do :\ncellsPerZoneX_ = std::round(stride_ / static_cast<double>(kAwbStatsSizeX));\n\nBut we haven't included stride yet :-)\n\n> \n>> +\n>> +\treturn 0;\n>> +}\n>> +\n>>  /**\n>>   * The function estimates the correlated color temperature using\n>>   * from RGB color space input.\n>> @@ -205,7 +222,7 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>>  \tfor (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {\n>>  \t\tRGB zone;\n>>  \t\tdouble counted = awbStats_[i].counted;\n>> -\t\tif (counted >= kMinZonesCounted) {\n>> +\t\tif (counted >= cellsPerZoneThreshold_) {\n>>  \t\t\tzone.G = awbStats_[i].sum.green / counted;\n>>  \t\t\tif (zone.G >= kMinGreenLevelInZone) {\n>>  \t\t\t\tzone.R = awbStats_[i].sum.red / counted;\n>> @@ -220,19 +237,16 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>>  void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,\n>>  \t\t\t   const ipu3_uapi_grid_config &grid)\n>>  {\n>> -\tuint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n>> -\tuint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n>> -\n>>  \t/*\n>>  \t * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is\n>>  \t * (grid.width x grid.height).\n>>  \t */\n>> -\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {\n>> -\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {\n>> +\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n>> +\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n>>  \t\t\tuint32_t cellPosition = (cellY * grid.width + cellX)\n>>  \t\t\t\t\t      * sizeof(Ipu3AwbCell);\n>> -\t\t\tuint32_t zoneX = cellX / cellsPerZoneX;\n>> -\t\t\tuint32_t zoneY = cellY / cellsPerZoneY;\n>> +\t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n>> +\t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n>>  \n>>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n>>  \n>> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n>> index 3385ebe7..681d8c2b 100644\n>> --- a/src/ipa/ipu3/algorithms/awb.h\n>> +++ b/src/ipa/ipu3/algorithms/awb.h\n>> @@ -48,6 +48,7 @@ public:\n>>  \tAwb();\n>>  \t~Awb();\n>>  \n>> +\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n>>  \tvoid prepare(IPAContext &context, ipu3_uapi_params *params) override;\n>>  \tvoid process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;\n>>  \n>> @@ -85,6 +86,10 @@ private:\n>>  \tstd::vector<RGB> zones_;\n>>  \tAccumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];\n>>  \tAwbStatus asyncResults_;\n>> +\n>> +\tuint32_t cellsPerZoneX_;\n>> +\tuint32_t cellsPerZoneY_;\n>> +\tuint32_t cellsPerZoneThreshold_;\n>>  };\n>>  \n>>  } /* namespace ipa::ipu3::algorithms */\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 3DFD7BDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Sep 2021 12:32:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0840D691AC;\n\tWed, 29 Sep 2021 14:32:04 +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 49FFA69185\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Sep 2021 14:32:03 +0200 (CEST)","from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:b4ce:851b:eca:f3fe])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 010353F0;\n\tWed, 29 Sep 2021 14:32:02 +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=\"l4vdZkAF\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632918723;\n\tbh=HgAqfQQr3/mQngGse+PfkepLkQ4h9tDhqf/iTl7vcfo=;\n\th=Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=l4vdZkAFl7RMYF0s4YvHOv/pPeJerue3DHFFh7DvNQy+hc5+knQyIunIykBOdJVWA\n\tW/PVLLoHpRKAng0+U2WiNmJ7CZrI2YRZGvW1WHuaedzPjzrXkDFIyj5GNeOJm2yxZb\n\tVyKVGPPLtbCjKVO0ZrBCC1JCVG53GPgV7f/TRXcQ=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20210923081625.60276-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>\n\t<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<dfdabd20-912e-d2a3-c255-8161b08293c8@ideasonboard.com>","Date":"Wed, 29 Sep 2021 14:32:00 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.13.0","MIME-Version":"1.0","In-Reply-To":"<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19995,"web_url":"https://patchwork.libcamera.org/comment/19995/","msgid":"<YVRdwyCz75BgexvC@pendragon.ideasonboard.com>","date":"2021-09-29T12:36:19","subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nOn Wed, Sep 29, 2021 at 02:32:00PM +0200, Jean-Michel Hautbois wrote:\n> On 29/09/2021 14:15, Laurent Pinchart wrote:\n> > On Thu, Sep 23, 2021 at 10:16:20AM +0200, Jean-Michel Hautbois wrote:\n> >> The algorithm uses the statistics of a cell only if there is not too\n> >> much saturated pixels in it. The grey world algorithm works fine when\n> >> there are a limited number of outliers.\n> >> Consider a valid zone to be at least 80% of unsaturated cells in it.\n> >> This value could very well be configurable, and make the algorithm more\n> >> or less tolerant.\n> >>\n> >> While at it, implement it in a configure() call as it will not change\n> >> during execution, and cache the cellsPerZone values.\n> >>\n> >> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> >> ---\n> >>  src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++---------\n> >>  src/ipa/ipu3/algorithms/awb.h   |  5 +++++\n> >>  2 files changed, 28 insertions(+), 9 deletions(-)\n> >>\n> >> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n> >> index 51a38d05..800d023c 100644\n> >> --- a/src/ipa/ipu3/algorithms/awb.cpp\n> >> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n> >> @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {\n> >>  \n> >>  LOG_DEFINE_CATEGORY(IPU3Awb)\n> >>  \n> >> -static constexpr uint32_t kMinZonesCounted = 16;\n> >>  static constexpr uint32_t kMinGreenLevelInZone = 32;\n> >>  \n> >>  /**\n> >> @@ -169,6 +168,24 @@ Awb::Awb()\n> >>  \n> >>  Awb::~Awb() = default;\n> >>  \n> >> +int Awb::configure(IPAContext &context,\n> >> +\t\t   [[maybe_unused]] const IPAConfigInfo &configInfo)\n> >> +{\n> >> +\tconst ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;\n> >> +\n> >> +\tcellsPerZoneX_ = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> > \n> > s/round/std::round/\n> > \n> > as you're using cmath (with a small corresponding comment in the commit\n> > message).\n> \n> OK :-).\n> \n> >> +\tcellsPerZoneY_ = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> >> +\n> >> +\t/*\n> >> +\t * Configure the minimum proportion of cells counted within a zone\n> >> +\t * for it to be relevant for the grey world algorithm.\n> >> +\t * \\todo This proportion could be configured.\n> >> +\t */\n> >> +\tcellsPerZoneThreshold_ = (cellsPerZoneX_ * cellsPerZoneY_) * 80 / 100;\n> > \n> > No need for parentheses.\n> > \n> > The patch looks fine to me, so\n> > \n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > \n> > This however led me to notice that if the grid width isn't a multiple of\n> > 16, we'll ignore some of the cells. If the grid width is 79, for\n> > instance, 15 cells will be ignored. Would it be worth fixing that ?\n> \n> We could still do :\n> cellsPerZoneX_ = std::round(stride_ / static_cast<double>(kAwbStatsSizeX));\n> \n> But we haven't included stride yet :-)\n\nI think the best solution for this issue may be a variable number of\ncells per zone. The question still holds though, is this an issue that\nneeds to be addressed, or is it harmless in practice ?\n\n> >> +\n> >> +\treturn 0;\n> >> +}\n> >> +\n> >>  /**\n> >>   * The function estimates the correlated color temperature using\n> >>   * from RGB color space input.\n> >> @@ -205,7 +222,7 @@ void Awb::generateZones(std::vector<RGB> &zones)\n> >>  \tfor (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {\n> >>  \t\tRGB zone;\n> >>  \t\tdouble counted = awbStats_[i].counted;\n> >> -\t\tif (counted >= kMinZonesCounted) {\n> >> +\t\tif (counted >= cellsPerZoneThreshold_) {\n> >>  \t\t\tzone.G = awbStats_[i].sum.green / counted;\n> >>  \t\t\tif (zone.G >= kMinGreenLevelInZone) {\n> >>  \t\t\t\tzone.R = awbStats_[i].sum.red / counted;\n> >> @@ -220,19 +237,16 @@ void Awb::generateZones(std::vector<RGB> &zones)\n> >>  void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,\n> >>  \t\t\t   const ipu3_uapi_grid_config &grid)\n> >>  {\n> >> -\tuint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n> >> -\tuint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n> >> -\n> >>  \t/*\n> >>  \t * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is\n> >>  \t * (grid.width x grid.height).\n> >>  \t */\n> >> -\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {\n> >> -\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {\n> >> +\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n> >> +\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n> >>  \t\t\tuint32_t cellPosition = (cellY * grid.width + cellX)\n> >>  \t\t\t\t\t      * sizeof(Ipu3AwbCell);\n> >> -\t\t\tuint32_t zoneX = cellX / cellsPerZoneX;\n> >> -\t\t\tuint32_t zoneY = cellY / cellsPerZoneY;\n> >> +\t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n> >> +\t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n> >>  \n> >>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n> >>  \n> >> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n> >> index 3385ebe7..681d8c2b 100644\n> >> --- a/src/ipa/ipu3/algorithms/awb.h\n> >> +++ b/src/ipa/ipu3/algorithms/awb.h\n> >> @@ -48,6 +48,7 @@ public:\n> >>  \tAwb();\n> >>  \t~Awb();\n> >>  \n> >> +\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n> >>  \tvoid prepare(IPAContext &context, ipu3_uapi_params *params) override;\n> >>  \tvoid process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;\n> >>  \n> >> @@ -85,6 +86,10 @@ private:\n> >>  \tstd::vector<RGB> zones_;\n> >>  \tAccumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];\n> >>  \tAwbStatus asyncResults_;\n> >> +\n> >> +\tuint32_t cellsPerZoneX_;\n> >> +\tuint32_t cellsPerZoneY_;\n> >> +\tuint32_t cellsPerZoneThreshold_;\n> >>  };\n> >>  \n> >>  } /* namespace ipa::ipu3::algorithms */","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 C6860C3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Sep 2021 12:36:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2BB2C691AA;\n\tWed, 29 Sep 2021 14:36:23 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B35F769185\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Sep 2021 14:36:21 +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 247A63F0;\n\tWed, 29 Sep 2021 14:36:21 +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=\"CW8jrP0m\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632918981;\n\tbh=eDhOn4gQ0dgKXHvtNA9Vz//VripIdLgplFQE5eM2a70=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=CW8jrP0mBTzk+944R5iErYKRkI68d4KETuKVfgVOLL8cMPYEwA5jGCrHKfJU1cj6N\n\tXUpYLN0Bh54l4/7nQOyKmu2SQVkwDtHqImpJnpbRqwDJ1G3o0OTIxiJwPLyvhDHum2\n\t5J7KG+5C7P0XvhqBXtspWOOZe30OAb+Nvt3c3OPA=","Date":"Wed, 29 Sep 2021 15:36:19 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<YVRdwyCz75BgexvC@pendragon.ideasonboard.com>","References":"<20210923081625.60276-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>\n\t<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>\n\t<dfdabd20-912e-d2a3-c255-8161b08293c8@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<dfdabd20-912e-d2a3-c255-8161b08293c8@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":20011,"web_url":"https://patchwork.libcamera.org/comment/20011/","msgid":"<240a89c9-9074-0b26-f182-ae81d9ff82c6@ideasonboard.com>","date":"2021-09-30T08:54:29","subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 29/09/2021 14:36, Laurent Pinchart wrote:\n> Hi Jean-Michel,\n> \n> On Wed, Sep 29, 2021 at 02:32:00PM +0200, Jean-Michel Hautbois wrote:\n>> On 29/09/2021 14:15, Laurent Pinchart wrote:\n>>> On Thu, Sep 23, 2021 at 10:16:20AM +0200, Jean-Michel Hautbois wrote:\n>>>> The algorithm uses the statistics of a cell only if there is not too\n>>>> much saturated pixels in it. The grey world algorithm works fine when\n>>>> there are a limited number of outliers.\n>>>> Consider a valid zone to be at least 80% of unsaturated cells in it.\n>>>> This value could very well be configurable, and make the algorithm more\n>>>> or less tolerant.\n>>>>\n>>>> While at it, implement it in a configure() call as it will not change\n>>>> during execution, and cache the cellsPerZone values.\n>>>>\n>>>> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n>>>> ---\n>>>>  src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++---------\n>>>>  src/ipa/ipu3/algorithms/awb.h   |  5 +++++\n>>>>  2 files changed, 28 insertions(+), 9 deletions(-)\n>>>>\n>>>> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n>>>> index 51a38d05..800d023c 100644\n>>>> --- a/src/ipa/ipu3/algorithms/awb.cpp\n>>>> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n>>>> @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {\n>>>>  \n>>>>  LOG_DEFINE_CATEGORY(IPU3Awb)\n>>>>  \n>>>> -static constexpr uint32_t kMinZonesCounted = 16;\n>>>>  static constexpr uint32_t kMinGreenLevelInZone = 32;\n>>>>  \n>>>>  /**\n>>>> @@ -169,6 +168,24 @@ Awb::Awb()\n>>>>  \n>>>>  Awb::~Awb() = default;\n>>>>  \n>>>> +int Awb::configure(IPAContext &context,\n>>>> +\t\t   [[maybe_unused]] const IPAConfigInfo &configInfo)\n>>>> +{\n>>>> +\tconst ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;\n>>>> +\n>>>> +\tcellsPerZoneX_ = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n>>>\n>>> s/round/std::round/\n>>>\n>>> as you're using cmath (with a small corresponding comment in the commit\n>>> message).\n>>\n>> OK :-).\n>>\n>>>> +\tcellsPerZoneY_ = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n>>>> +\n>>>> +\t/*\n>>>> +\t * Configure the minimum proportion of cells counted within a zone\n>>>> +\t * for it to be relevant for the grey world algorithm.\n>>>> +\t * \\todo This proportion could be configured.\n>>>> +\t */\n>>>> +\tcellsPerZoneThreshold_ = (cellsPerZoneX_ * cellsPerZoneY_) * 80 / 100;\n>>>\n>>> No need for parentheses.\n>>>\n>>> The patch looks fine to me, so\n>>>\n>>> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>>\n>>> This however led me to notice that if the grid width isn't a multiple of\n>>> 16, we'll ignore some of the cells. If the grid width is 79, for\n>>> instance, 15 cells will be ignored. Would it be worth fixing that ?\n>>\n>> We could still do :\n>> cellsPerZoneX_ = std::round(stride_ / static_cast<double>(kAwbStatsSizeX));\n>>\n>> But we haven't included stride yet :-)\n> \n> I think the best solution for this issue may be a variable number of\n> cells per zone. The question still holds though, is this an issue that\n> needs to be addressed, or is it harmless in practice ?\n> \n\nI think it is not needed, as it would not improve the behavior\nsignificantly imo (I may be wrong though !).\n\n>>>> +\n>>>> +\treturn 0;\n>>>> +}\n>>>> +\n>>>>  /**\n>>>>   * The function estimates the correlated color temperature using\n>>>>   * from RGB color space input.\n>>>> @@ -205,7 +222,7 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>>>>  \tfor (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {\n>>>>  \t\tRGB zone;\n>>>>  \t\tdouble counted = awbStats_[i].counted;\n>>>> -\t\tif (counted >= kMinZonesCounted) {\n>>>> +\t\tif (counted >= cellsPerZoneThreshold_) {\n>>>>  \t\t\tzone.G = awbStats_[i].sum.green / counted;\n>>>>  \t\t\tif (zone.G >= kMinGreenLevelInZone) {\n>>>>  \t\t\t\tzone.R = awbStats_[i].sum.red / counted;\n>>>> @@ -220,19 +237,16 @@ void Awb::generateZones(std::vector<RGB> &zones)\n>>>>  void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,\n>>>>  \t\t\t   const ipu3_uapi_grid_config &grid)\n>>>>  {\n>>>> -\tuint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));\n>>>> -\tuint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));\n>>>> -\n>>>>  \t/*\n>>>>  \t * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is\n>>>>  \t * (grid.width x grid.height).\n>>>>  \t */\n>>>> -\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {\n>>>> -\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {\n>>>> +\tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n>>>> +\t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n>>>>  \t\t\tuint32_t cellPosition = (cellY * grid.width + cellX)\n>>>>  \t\t\t\t\t      * sizeof(Ipu3AwbCell);\n>>>> -\t\t\tuint32_t zoneX = cellX / cellsPerZoneX;\n>>>> -\t\t\tuint32_t zoneY = cellY / cellsPerZoneY;\n>>>> +\t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n>>>> +\t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n>>>>  \n>>>>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n>>>>  \n>>>> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n>>>> index 3385ebe7..681d8c2b 100644\n>>>> --- a/src/ipa/ipu3/algorithms/awb.h\n>>>> +++ b/src/ipa/ipu3/algorithms/awb.h\n>>>> @@ -48,6 +48,7 @@ public:\n>>>>  \tAwb();\n>>>>  \t~Awb();\n>>>>  \n>>>> +\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n>>>>  \tvoid prepare(IPAContext &context, ipu3_uapi_params *params) override;\n>>>>  \tvoid process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;\n>>>>  \n>>>> @@ -85,6 +86,10 @@ private:\n>>>>  \tstd::vector<RGB> zones_;\n>>>>  \tAccumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];\n>>>>  \tAwbStatus asyncResults_;\n>>>> +\n>>>> +\tuint32_t cellsPerZoneX_;\n>>>> +\tuint32_t cellsPerZoneY_;\n>>>> +\tuint32_t cellsPerZoneThreshold_;\n>>>>  };\n>>>>  \n>>>>  } /* namespace ipa::ipu3::algorithms */\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 B9971C3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Sep 2021 08:54:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1B3ED691AB;\n\tThu, 30 Sep 2021 10:54:34 +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 6430969189\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Sep 2021 10:54:32 +0200 (CEST)","from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:bab4:22c5:662d:e478])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F03142A8;\n\tThu, 30 Sep 2021 10:54:31 +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=\"tqnAGwbM\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632992072;\n\tbh=USANFQwL8O7lZqA2h0k881G/92fQby5m4rMYPfuZ5rg=;\n\th=Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=tqnAGwbMaNMvkDujNwzLCZHVAZxgF4E6JbUs2e5uVg9PAdnMvBBDvKgzLfTL+/8sl\n\tdFukI0abMCSZq6K0BwA/CgndDxK+huFoFyKRNN2/LUbrD+w8NQToGLvPawrjYfbeNs\n\tpaqTTBMaLri6YF9uH368ftEJLtVhgHHIQZDbjilU=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20210923081625.60276-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210923081625.60276-8-jeanmichel.hautbois@ideasonboard.com>\n\t<YVRY9vJixgyAYNJ7@pendragon.ideasonboard.com>\n\t<dfdabd20-912e-d2a3-c255-8161b08293c8@ideasonboard.com>\n\t<YVRdwyCz75BgexvC@pendragon.ideasonboard.com>","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<240a89c9-9074-0b26-f182-ae81d9ff82c6@ideasonboard.com>","Date":"Thu, 30 Sep 2021 10:54:29 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.13.0","MIME-Version":"1.0","In-Reply-To":"<YVRdwyCz75BgexvC@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH 07/12] ipa: ipu3: awb: Correct the\n\trelevant zones proportion","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]