From patchwork Wed Oct 6 14:00:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 14061 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E3E51C323E for ; Wed, 6 Oct 2021 14:01:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A33F4691BF; Wed, 6 Oct 2021 16:01:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fPkpxKOL"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 60136691C2 for ; Wed, 6 Oct 2021 16:01:02 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:843b:c831:54de:6e8c]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1161E1909; Wed, 6 Oct 2021 16:01:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1633528862; bh=xoWuOp6/4P9/LAbzl7B9GMLLcrfZ/5bjwLZ3tnhnxGo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fPkpxKOLsqMY4imnE1QUo2W+4/h8T+2d2i9D2KGxRVZmiZmighYX3Uo04wZJ8gRVw EazXdAyDBKfGKeyFJ+rku4I5SnJbDkSN8bWi6Gztfhj3EBVNYwx6G6n9za1VbOgk9i /da7jTqhe5BAKG/JKiKLIcvUV6+N5STzpRfJweSA= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Oct 2021 16:00:37 +0200 Message-Id: <20211006140041.964542-8-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211006140041.964542-1-jeanmichel.hautbois@ideasonboard.com> References: <20211006140041.964542-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 07/12] ipa: ipu3: awb: Correct the relevant zones proportion X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The algorithm uses the statistics of a cell only if there is not too much saturated pixels in it. The grey world algorithm works fine when there are a limited number of outliers. Consider a valid zone to be at least 80% of unsaturated cells in it. This value could very well be configurable, and make the algorithm more or less tolerant. While at it, implement it in a configure() call as it will not change during execution, and cache the cellsPerZone values estimated with std::round as we are using cmath. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/algorithms/awb.cpp | 32 +++++++++++++++++++++++--------- src/ipa/ipu3/algorithms/awb.h | 5 +++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp index dba7cec3..1c294f31 100644 --- a/src/ipa/ipu3/algorithms/awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Awb) -static constexpr uint32_t kMinZonesCounted = 16; static constexpr uint32_t kMinGreenLevelInZone = 32; /** @@ -173,6 +172,24 @@ Awb::Awb() Awb::~Awb() = default; +int Awb::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid; + + cellsPerZoneX_ = std::round(grid.width / static_cast(kAwbStatsSizeX)); + cellsPerZoneY_ = std::round(grid.height / static_cast(kAwbStatsSizeY)); + + /* + * Configure the minimum proportion of cells counted within a zone + * for it to be relevant for the grey world algorithm. + * \todo This proportion could be configured. + */ + cellsPerZoneThreshold_ = cellsPerZoneX_ * cellsPerZoneY_ * 80 / 100; + + return 0; +} + /** * The function estimates the correlated color temperature using * from RGB color space input. @@ -209,7 +226,7 @@ void Awb::generateZones(std::vector &zones) for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) { RGB zone; double counted = awbStats_[i].counted; - if (counted >= kMinZonesCounted) { + if (counted >= cellsPerZoneThreshold_) { zone.G = awbStats_[i].sum.green / counted; if (zone.G >= kMinGreenLevelInZone) { zone.R = awbStats_[i].sum.red / counted; @@ -224,19 +241,16 @@ void Awb::generateZones(std::vector &zones) void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats, const ipu3_uapi_grid_config &grid) { - uint32_t cellsPerZoneX = round(grid.width / static_cast(kAwbStatsSizeX)); - uint32_t cellsPerZoneY = round(grid.height / static_cast(kAwbStatsSizeY)); - /* * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is * (grid.width x grid.height). */ - for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) { - for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) { + for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) { + for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) { uint32_t cellPosition = (cellY * grid.width + cellX) * sizeof(Ipu3AwbCell); - uint32_t zoneX = cellX / cellsPerZoneX; - uint32_t zoneY = cellY / cellsPerZoneY; + uint32_t zoneX = cellX / cellsPerZoneX_; + uint32_t zoneY = cellY / cellsPerZoneY_; uint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX; diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h index 3385ebe7..681d8c2b 100644 --- a/src/ipa/ipu3/algorithms/awb.h +++ b/src/ipa/ipu3/algorithms/awb.h @@ -48,6 +48,7 @@ public: Awb(); ~Awb(); + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void prepare(IPAContext &context, ipu3_uapi_params *params) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; @@ -85,6 +86,10 @@ private: std::vector zones_; Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; AwbStatus asyncResults_; + + uint32_t cellsPerZoneX_; + uint32_t cellsPerZoneY_; + uint32_t cellsPerZoneThreshold_; }; } /* namespace ipa::ipu3::algorithms */