Patch Detail
Show a patch.
GET /api/patches/19865/?format=api
{ "id": 19865, "url": "https://patchwork.libcamera.org/api/patches/19865/?format=api", "web_url": "https://patchwork.libcamera.org/patch/19865/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20240412091700.1817754-2-paul.elder@ideasonboard.com>", "date": "2024-04-12T09:16:58", "name": "[1/3] ipa: libipa: Add Lux helper", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "27071beaa96673056515969cf7e2ff4c0525f4a7", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/19865/mbox/", "series": [ { "id": 4255, "url": "https://patchwork.libcamera.org/api/series/4255/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4255", "date": "2024-04-12T09:16:57", "name": "ipa: rkisp1: Add lux estimation", "version": 1, "mbox": "https://patchwork.libcamera.org/series/4255/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/19865/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/19865/checks/", "tags": {}, "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 7FDF2C3285\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 12 Apr 2024 09:17:17 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B295D63365;\n\tFri, 12 Apr 2024 11:17:16 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E80816334D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 12 Apr 2024 11:17:14 +0200 (CEST)", "from pyrite.hamster-moth.ts.net (h175-177-049-156.catv02.itscom.jp\n\t[175.177.49.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7496EA68;\n\tFri, 12 Apr 2024 11:16:30 +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=\"Rg8rbsXO\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1712913391;\n\tbh=D439QK52+qfT/ZkMkznJtkTLpW05cf4Otgc9lSuDJdE=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Rg8rbsXOXgWzFnhg3FO6GeP6MRrwT0KyoEl1YZhjjMU6SVRLFG0NaUqMMGectLNFY\n\tpZsZ2vEY17iFRfjdsk1o/7nnVyaXjJNjhb4tk5eiCH7ro4UUQVSllSFCbX5p2QVoxr\n\tsIVuDHxNF9ZcKLPJdLTZdX2frB4dWi16JEyeB3ag=", "From": "Paul Elder <paul.elder@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Paul Elder <paul.elder@ideasonboard.com>", "Subject": "[PATCH 1/3] ipa: libipa: Add Lux helper", "Date": "Fri, 12 Apr 2024 18:16:58 +0900", "Message-Id": "<20240412091700.1817754-2-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.39.2", "In-Reply-To": "<20240412091700.1817754-1-paul.elder@ideasonboard.com>", "References": "<20240412091700.1817754-1-paul.elder@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "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>" }, "content": "Add a Lux helper to libipa that does the estimation of the lux level\ngiven gain, exposure, aperture, and luminance histogram. The helper also\nhandles reading the reference values from the tuning file. These are\nexpected to be common operations of lux algorithm modules in IPAs, and\nis modeled/copied from Raspberry Pi.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n---\n src/ipa/libipa/lux.cpp | 119 +++++++++++++++++++++++++++++++++++++\n src/ipa/libipa/lux.h | 45 ++++++++++++++\n src/ipa/libipa/meson.build | 2 +\n 3 files changed, 166 insertions(+)\n create mode 100644 src/ipa/libipa/lux.cpp\n create mode 100644 src/ipa/libipa/lux.h", "diff": "diff --git a/src/ipa/libipa/lux.cpp b/src/ipa/libipa/lux.cpp\nnew file mode 100644\nindex 00000000..756cd3c4\n--- /dev/null\n+++ b/src/ipa/libipa/lux.cpp\n@@ -0,0 +1,119 @@\n+/* SPDX-License-Identifier: BSD-2-Clause */\n+/*\n+ * Copyright (C) 2019, Raspberry Pi Ltd\n+ * Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>\n+ *\n+ * lux.h - Helper class that implements lux estimation\n+ */\n+#include \"lux.h\"\n+\n+#include <algorithm>\n+#include <chrono>\n+\n+#include <libcamera/base/log.h>\n+\n+#include \"libcamera/internal/yaml_parser.h\"\n+\n+#include \"histogram.h\"\n+\n+/**\n+ * \\file lux.h\n+ * \\brief Helper class that implements lux estimation\n+ *\n+ * As estimating the lux level of an image is expected to be a common\n+ * operation, it is implemented in a helper in libipa.\n+ */\n+\n+namespace libcamera {\n+\n+using namespace std::literals::chrono_literals;\n+\n+LOG_DEFINE_CATEGORY(Lux)\n+\n+namespace ipa {\n+\n+/**\n+ * \\class Lux\n+ * \\brief Class that implements lux estimation\n+ */\n+\n+/**\n+ * \\var Lux::referenceExposureTime_\n+ * \\brief The exposure time of the reference image, in microseconds.\n+ */\n+\n+/**\n+ * \\var Lux::referenceGain_\n+ * \\brief The analogue gain of the reference image.\n+ */\n+\n+/**\n+ * \\var Lux::referenceAperture_\n+ * \\brief The aperture of the reference image in units of 1/f.\n+ */\n+\n+/**\n+ * \\var Lux::referenceY_\n+ * \\brief The measured luminance of the reference image, out of 65536.\n+ */\n+\n+/**\n+ * \\var Lux::referenceLux_\n+ * \\brief The estimated lux level of the reference image.\n+ */\n+\n+int Lux::readYaml(const YamlObject &tuningData)\n+{\n+\tauto value = tuningData[\"reference_exposure_time\"].get<double>();\n+\tif (!value) {\n+\t\tLOG(Lux, Error) << \"Missing tuning parameter: 'reference_exposure_time'\";\n+\t\treturn -EINVAL;\n+\t}\n+\treferenceExposureTime_ = *value * 1.0us;\n+\n+\tvalue = tuningData[\"reference_gain\"].get<double>();\n+\tif (!value) {\n+\t\tLOG(Lux, Error) << \"Missing tuning parameter: 'reference_gain'\";\n+\t\treturn -EINVAL;\n+\t}\n+\treferenceGain_ = *value;\n+\n+\treferenceAperture_ = tuningData[\"reference_aperture\"].get<double>(1.0);\n+\n+\tvalue = tuningData[\"reference_Y\"].get<double>();\n+\tif (!value) {\n+\t\tLOG(Lux, Error) << \"Missing tuning parameter: 'reference_Y'\";\n+\t\treturn -EINVAL;\n+\t}\n+\treferenceY_ = *value;\n+\n+\tvalue = tuningData[\"reference_lux\"].get<double>();\n+\tif (!value) {\n+\t\tLOG(Lux, Error) << \"Missing tuning parameter: 'reference_lux'\";\n+\t\treturn -EINVAL;\n+\t}\n+\treferenceLux_ = *value;\n+\n+\treturn 0;\n+}\n+\n+double Lux::process(double gain, utils::Duration exposureTime, double aperture,\n+\t\t const Histogram &yHist) const\n+{\n+\tdouble currentY = yHist.interQuantileMean(0, 1);\n+\tdouble gainRatio = referenceGain_ / gain;\n+\tdouble exposureTimeRatio = referenceExposureTime_ / exposureTime;\n+\tdouble apertureRatio = referenceAperture_ / aperture;\n+\tdouble yRatio = currentY * (65536 / yHist.bins()) / referenceY_;\n+\n+\tdouble estimatedLux = exposureTimeRatio * gainRatio *\n+\t\t\t apertureRatio * apertureRatio *\n+\t\t\t yRatio * referenceLux_;\n+\n+\tLOG(Lux, Debug) << \"Estimated lux \" << estimatedLux;\n+\treturn estimatedLux;\n+}\n+\n+} /* namespace ipa */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/libipa/lux.h b/src/ipa/libipa/lux.h\nnew file mode 100644\nindex 00000000..6bc9cf9f\n--- /dev/null\n+++ b/src/ipa/libipa/lux.h\n@@ -0,0 +1,45 @@\n+/* SPDX-License-Identifier: BSD-2-Clause */\n+/*\n+ * Copyright (C) 2019, Raspberry Pi Ltd\n+ * Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>\n+ *\n+ * lux.h - Helper class that implements lux estimation\n+ */\n+\n+#pragma once\n+\n+#include <algorithm>\n+#include <tuple>\n+#include <vector>\n+\n+#include <libcamera/base/utils.h>\n+\n+#include \"libcamera/internal/yaml_parser.h\"\n+\n+#include \"histogram.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa {\n+\n+class Lux\n+{\n+public:\n+\tLux() = default;\n+\t~Lux() = default;\n+\n+\tint readYaml(const YamlObject &tuningData);\n+\tdouble process(double gain, utils::Duration exposureTime,\n+\t\t double aperture, const Histogram &yHist) const;\n+\n+private:\n+\tutils::Duration referenceExposureTime_;\n+\tdouble referenceGain_;\n+\tdouble referenceAperture_;\n+\tdouble referenceY_;\n+\tdouble referenceLux_;\n+};\n+\n+} /* namespace ipa */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build\nindex 0796982e..b6d58900 100644\n--- a/src/ipa/libipa/meson.build\n+++ b/src/ipa/libipa/meson.build\n@@ -8,6 +8,7 @@ libipa_headers = files([\n 'exposure_mode_helper.h',\n 'fc_queue.h',\n 'histogram.h',\n+ 'lux.h',\n 'matrix.h',\n 'module.h',\n 'pwl.h',\n@@ -21,6 +22,7 @@ libipa_sources = files([\n 'exposure_mode_helper.cpp',\n 'fc_queue.cpp',\n 'histogram.cpp',\n+ 'lux.cpp',\n 'matrix.cpp',\n 'module.cpp',\n 'pwl.cpp'\n", "prefixes": [ "1/3" ] }