From patchwork Wed Jun 17 09:58:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 26911 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 E13F3BF415 for ; Wed, 17 Jun 2026 09:59:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8CA866289A; Wed, 17 Jun 2026 11:59:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ULl+NJod"; 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 1583562886 for ; Wed, 17 Jun 2026 11:59:08 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bba7:89ad:1437:cbea]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EEED397F; Wed, 17 Jun 2026 11:58:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1781690314; bh=/7yCmiMb9P+Gw1Nx0CCveA5uU/i8ed4pbSKg6BYXfao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ULl+NJodxWECuY8dGd3gD0SX3ZyBBBarg31u79EELq3vIUPw+mckhLeBbUWFpIIly 1qpmH2xR/isIGwdxf5IV8LFkDoevgi2ICPJZL/1J2ymn9joZLNTS0HLzduf4W0KHl2 +NBmEorh7arxjwvhddvk3xkXGEaO/9Dul8pzVdc8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH 2/2] libcamera: converter: converter_dw100: Allow to transform between different camera matrices Date: Wed, 17 Jun 2026 11:58:50 +0200 Message-ID: <20260617095857.667583-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260617095857.667583-1-stefan.klug@ideasonboard.com> References: <20260617095857.667583-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" For some use cases (like removing a skew introduced by the camera geometry) it is necessary to define the output 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 --- 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 787498c7fdb5..d60997f56ad5 100644 --- a/include/libcamera/internal/converter/converter_dw100_vertexmap.h +++ b/include/libcamera/internal/converter/converter_dw100_vertexmap.h @@ -33,11 +33,13 @@ public: struct DewarpParams { DewarpParams() : cm(Matrix::identity()), + cmNew(Matrix::identity()), coefficients({}) { } Matrix cm; + Matrix cmNew; union { struct { diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp index 34f81c6b9fab..97a025b7f961 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) { @@ -142,6 +143,18 @@ int ConverterDW100Module::init(const ValueNode ¶ms) std::copy(coeffs->begin(), coeffs->end(), &dp.coefficients[0]); + 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 31d992546857..22e08656d36d 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::coefficient * \brief Structure containing the lens dewarp coefficients @@ -619,10 +622,11 @@ Vector2d Dw100VertexMap::dewarpPoint(const Vector2d &p) double x, y; double xout, yout; auto &cm = dewarpParams_->cm; + auto &cmNew = dewarpParams_->cmNew; auto &c = dewarpParams_->coefficient; - 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;