如何将四边形投影为矩形?


10

tl; dr:射影几何中的数学问题:如何找到如下所示的投影的4x4相机矩阵,使得点A,B,C,D位于单位框的边缘某处(例如OpenGL归一化设备坐标),单位框的角沿EA,EB,EC,ED射线落在合理的位置?

(这可能是单应性,透视性和/或归类的一种特殊情况。不熟悉术语。)


细化

给定视口内的四边形ABCD,我认为存在一个独特的(?)转换,可将其映射回矩形。如下图所示:视口中的四边形ABCD充当物理“窗口”,如果我们将其映射回矩形,它将显得失真。

在此处输入图片说明

(右边的方框代表NDC,我稍后再谈)

目的是快速获得右侧的图像。我们可以用光线跟踪每个点来获取图像(我已经完成了),但是我更喜欢使用OpenGL或其他投影技术,因为我想利用诸如混合,基元之类的东西。

第一次尝试

我相信我可以解决以下问题:找到3x4 相机矩阵,该矩阵在3空间(在左侧)中使3 + 1维均匀坐标,然后将其投影到2空间(在2维上)具有2 + 1维均匀坐标(在左侧)正确的)。可以使用直接线性变换来解决此问题,以获得摄像机矩阵Ba=0未知项a的方程组,并使用奇异值分解来求解该系统(SVD)。我将向量EA,EB,EC,ED(其中E是您的肉眼或世界空间中的相机)作为原像中的点,并将(0,0),(1,0),(1 ,1),(0,1)之类的东西作为后图像中​​的点,并且每对点都会给出一些线性方程式以插入SVD。生成的矩阵将映射EA->(0,0)等。(假设有足够的自由度,即,如果解决方案是唯一的,那么我不确定,请参见注释[a]。)

但是令我烦恼的是,这不是OpenGL的工作方式。OpenGL不会直接使用3x4矩阵将3d投影到2d。OpenGL需要“归一化设备坐标”(NDC),它们是三维点。投影到NDC之后,将绘制“单位”框中从(-1,-1,-1,1)到(1,1,1,1)的所有内容;外部的所有内容都会被裁剪(因为我们正在处理同质坐标:仅当(x / w,y / w,z / w的前三个坐标)时,任何点(x,y,z,w)才会显示在屏幕上,1)在-1至1)的单位框中。

因此,问题就变成了:是否存在某种合理的变换,可以将一些看起来怪异的长方体映射到均质坐标中(特别是在左侧绘制的长方体,其ABCD(前端)和A'B'C'D'(后端,隐藏)在前端后面))到单位立方体,例如使用4x4矩阵?怎么做?

我尝试过的

我已经尝试了一些更强大的方法:我使ABCD和A'B'C'D'看起来像是普通的锥体平截头圆锥体(例如gl平截头体)(即,在这种假设的设置中,左侧的图像只是在其上叠加了一个黑色矩形)而不是四边形),然后使用DLT /直接线性变换来求解所谓的4x4矩阵。但是,当我尝试它时,似乎没有足够的自由度...生成的4x4矩阵并未将每个输入向量映射到每个输出向量。在使用A,B,C,D,A'(5对转换前和转换后向量)时,我/几乎/得到了我想要的结果...这些向量已正确映射,但是例如B', C',D'映射到(3,3,1,1)而不是(-1,-1,1,1),并被OpenGL裁剪掉。如果我尝试添加第六点(用于投影4x4矩阵的6对点),我的解决方案似乎退化(零,无限)。我在这里要处理多少自由度,并且使用4x4矩阵映射我们知道和喜欢的4个向量(3 + 1维齐次坐标向量)是否有可能?

随意的小想法

我猜想不可能将任意长方体映射到具有4x4矩阵的任意长方体,尽管我很困惑,因为我认为可以使用2D中的某些矩阵在2d中将任何凸四边形映射到任何其他凸四边形。 ,例如,Photoshop?...不能/不能通过投影变换来完成吗?以及如何将其推广到3d?......同样,由于未能找到4x4矩阵,线性代数表示,在最佳情况下,我们不应该期望NxN矩阵将N个以上线性独立的点映射到N个目标点,但是我觉得这是同质的协调作弊这是因为存在一些隐藏的共线性吗?我猜不会?

另一个解决方案?

我猜可能还可以做以下丑事:使用典型的平截头体相机投影矩阵,找到与角对应的2D点,然后执行2D透视变形单应性,但是如果在渲染像素之后发生(例如photoshop),那么分辨率就会出现问题……也许假设可以找出一个矩阵在NDC空间内的XY平面上执行此转换,然后将其与基于普通视锥峰的矩阵组合起来?

(注释[a]:自由度:如果需要的话,可以将ABCD进一步约束为作用在矩形上的投影变换的后图像...可以说是左侧的黑色矩形是投影相框剪贴画模型的结果)


1
如果您用谷歌搜索角钉,您将获得一些实现
joojaa

Answers:


1

我认为解决方案正在寻找能够正确转换四个点的投影转换。

y=P×x

其中和x=[x0,x1,1]y=[y0y2,y1y2]

P是一个具有9个条目的3x3矩阵。由于最终归一化,它在缩放之前是唯一的,剩下8个自由度,这由对应关系给出的8个方程式唯一确定(每对点2个)。

现在,您可以使用代数执行此操作,或者仅使用OpenCV的getPerspectiveTransform:)。

还可以在Wikipedia上查看同类坐标,以熟悉该概念。


谢谢!(我不久前解决了这个问题,并在看到您的评论时才发布解决方案。)
ninjagecko

0

我通过实现直接线性变换解决了自己的问题。维基百科上的示例部分是我的用例。

要获取方程式,请将矩阵(例如[x1 x2 x3 x4; x5 x6 x7 x8; x9 x10 x11 x12])插入您喜欢的计算机代数系统(如SageMath)中,然后如图所示求解所需的矩阵方程式,将变量形式的解复制粘贴到您的代码中,并调整格式。

然后,可以通过按比例缩放或忽略特定尺寸来使解决方案适合自己的用例(例如,根据用例忽略标准化设备坐标矩阵中的深度/ z坐标)。

您将需要使用您的语言的SVD分解功能或库。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.