From patchwork Thu Jul 9 12:41:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 27358 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 BAFCBBF415 for ; Thu, 9 Jul 2026 12:42:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 669CC66101; Thu, 9 Jul 2026 14:42:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dyAVFLax"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0F771660E3 for ; Thu, 9 Jul 2026 14:42:12 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:b99c:646e:18fa:5ff]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 911F5153F; Thu, 9 Jul 2026 14:41:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1783600881; bh=HE50nK1cOnAoYdxMfQE9JzW6tQ67uJpKtqbzbImaabI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dyAVFLaxIK9+XBbUpobwgAg9fXB9FSbvKkewHEadVQE5m1zj/QOQfhW/aXLewvHJe PmDgi0dsZo6SxaJvi/VEOtwm3ysliYP+2tRPrcs3G42wXLzgWM4WZ88GoH1ZwrU9po EZBKdIx4gGGojwrOOvMhBdHIenyG5vo52xd9/gX8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham , Paul Elder Subject: [PATCH v3 2/2] libcamera: converter: converter_dw100: Allow to transform between different camera matrices Date: Thu, 9 Jul 2026 14:41:51 +0200 Message-ID: <20260709124159.387110-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260709124159.387110-1-stefan.klug@ideasonboard.com> References: <20260709124159.387110-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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" To configure the lens dewarping, the calibrated camera matrix and the distortion coefficients are required. For some use cases (like removing a skew introduced by the camera geometry) it is necessary to define an additional output camera matrix often called "new camera matrix". Add that functionality by adding an optional tuning parameter "cmNew" to the Dewarp configuration. If that parameter is not provided, cm is used instead. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- Changes in v3: - Improved commit message - Collected tags - Fixed code wrapping Changes in v0.2: - Swapped cm and cmNew in the output calculation --- .../converter/converter_dw100_vertexmap.h | 2 ++ src/libcamera/converter/converter_dw100.cpp | 15 ++++++++++++++- .../converter/converter_dw100_vertexmap.cpp | 8 ++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/libcamera/internal/converter/converter_dw100_vertexmap.h b/include/libcamera/internal/converter/converter_dw100_vertexmap.h index 1f2f9c88e8e8..8cb86ed546f6 100644 --- a/include/libcamera/internal/converter/converter_dw100_vertexmap.h +++ b/include/libcamera/internal/converter/converter_dw100_vertexmap.h @@ -34,6 +34,7 @@ public: struct DewarpParams { DewarpParams() : cm(Matrix::identity()), + cmNew(Matrix::identity()), coefficients({}) { } @@ -41,6 +42,7 @@ public: int setCoefficients(Span coeffs); Matrix cm; + Matrix cmNew; struct { double k1; diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp index d05823fa4d4c..77f778c7f103 100644 --- a/src/libcamera/converter/converter_dw100.cpp +++ b/src/libcamera/converter/converter_dw100.cpp @@ -104,9 +104,10 @@ int ConverterDW100Module::init(const ValueNode ¶ms) auto &cm = params["cm"]; auto &coefficients = params["coefficients"]; + auto &cmNew = params["cmNew"]; /* If nothing is provided, the dewarper is still functional */ - if (!cm && !coefficients) + if (!cm && !coefficients && !cmNew) return 0; if (!cm) { @@ -140,6 +141,18 @@ int ConverterDW100Module::init(const ValueNode ¶ms) return -EINVAL; } + if (cmNew) { + matrix = cmNew.get>(); + if (!matrix) { + LOG(Converter, Error) << "Failed to load 'cmNew' value"; + return -EINVAL; + } + + dp.cmNew = *matrix; + } else { + dp.cmNew = dp.cm; + } + dewarpParams_ = dp; return 0; diff --git a/src/libcamera/converter/converter_dw100_vertexmap.cpp b/src/libcamera/converter/converter_dw100_vertexmap.cpp index a990ab4952b4..d5fbfdaafde2 100644 --- a/src/libcamera/converter/converter_dw100_vertexmap.cpp +++ b/src/libcamera/converter/converter_dw100_vertexmap.cpp @@ -234,6 +234,9 @@ int dw100VerticesForLength(const int length) * \var Dw100VertexMap::DewarpParams::cm * \brief The camera matrix * + * \var Dw100VertexMap::DewarpParams::cmNew + * \brief The new camera matrix after dewarping + * * \var Dw100VertexMap::DewarpParams::coefficients * \brief Structure containing the lens dewarp coefficients @@ -665,10 +668,11 @@ Vector2d Dw100VertexMap::dewarpPoint(const Vector2d &p) double x, y; double xout, yout; auto &cm = dewarpParams_->cm; + auto &cmNew = dewarpParams_->cmNew; auto &c = dewarpParams_->coefficients; - y = (p.y() - cm[1][2]) / cm[1][1]; - x = (p.x() - cm[0][2] - y * cm[0][1]) / cm[0][0]; + y = (p.y() - cmNew[1][2]) / cmNew[1][1]; + x = (p.x() - cmNew[0][2] - y * cmNew[0][1]) / cmNew[0][0]; double r2 = x * x + y * y; double r4 = r2 * r2;