【问题标题】:Trying to derive a 2D transformation matrix using only the images尝试仅使用图像导出 2D 变换矩阵
【发布时间】:2009-12-06 18:50:59
【问题描述】:

我不知道这应该放在数学论坛还是编程论坛上,但我会在这两个论坛上发布,看看我能从哪里得到。

我有两张电脑图像...其中一张是“原始”图像(一个大的 TIF 文件)。另一个是原始图像的转换版本……它在软件程序中被旋转、剪切和翻译。我需要对转换后的图像做一些工作,但我需要原始图像中每个像素的 (x-y) 坐标来完成我的计算。

我知道图像是使用 3x3 变换矩阵旋转和剪切的。如果我有矩阵,我可以自己从第一个图像(反之亦然)推导出第二个图像。我不知道它被旋转、剪切或平移了多少,所以我不能只从一组已知的变换中推导出矩阵。我所拥有的是每个图像中的一组对应点(角等),以及它们对应的(x,y)坐标。所以这是我的困境:

使用一组对应的变换点((x,y) -> (x',y'),其中三个或更多),我可以推导出用于将一个图像转换为另一个图像的变换矩阵吗?如果我可以推导出矩阵,我就可以求解所有像素(全部为 1800 万个)的原始坐标,并完成我需要做的计算。

有人可以帮忙吗?我对线性代数很熟悉……只是不够熟悉,无法在不费力气的情况下得出这个结论。任何事情都值得赞赏!

  • 迈克

【问题讨论】:

  • 这个问题让我发疯了。请查看herehere。如果我只能将您的答案翻译成简单的编程。

标签: matrix transformation


【解决方案1】:

不确定您要手动还是自动...

手动

如果指定矩形四个角的变换坐标,则可以推导出变换方程:

alt text http://www.praeclarum.org/so/wellner.png

(来自 Pierre Wellner 的 Interacting with Paper on the DigitalDesk 以及他的 Thesis 中的更多详细信息)

现在您只需求解方程的系数。

使用四点对,可以通过高斯消元法快速求解两组四个联立线性方程组,求出c1-8的值。

最后,您可以将这些方程转换为您想要的 3x3 矩阵。上述方程足以进行非线性变换,您可以将其简化为 3x3 仿射剪切矩阵。

但我会坚持使用非线性方程(上图),因为它们可以处理透视失真

自动

同样的方法,但您可以使用边缘检测器与线检测算法相结合来找到构成矩形的一组 4 条线。

如果您的图像矩形真的很突出(深色背景上的白色图像),那么您可以使用OpenCV's Feature Detection 等库中提供的角检测(请参阅cvCornerHarris)。

您可以将这些线相交以找到四个角并使用变换方程。

【讨论】:

  • 我应该让 Mike 为自己说话,但我个人觉得完全无法理解您的解释。我认为我们中的许多人对数学只是顺便熟悉。
  • 哦。高斯消除在诸如“数值算法”之类的书中有很好的记录。但我想强调的是,这远远优于 3x3 仿射变换,因为它可以处理透视失真(非线性非仿射变换)。如果有兴趣,我可以扩展我的答案。
  • 评论跨度。我想补充一点,我在一个生产项目中使用了这种精确的方法,效果很好。如果我没有做到公正,我深表歉意,但不要让我的油嘴滑舌的描述引导你远离这种强大的技术。请阅读链接到的材料。
  • 这太完美了,弗兰克。我不认为这个解释是油嘴滑舌的,它给了我一张我需要做什么的地图。我敢肯定那里正在进行透视转换。我可以从 4 个非线性点推导出 c1-c8 常数……它们不必是角落,对吧?我只记得第二张图片中的两个角被剪掉了,但在这种情况下应该没关系......我可以使用许多非常不同的参考点。我将插入它们以转换其余部分。我不赞成使用 3x3 矩阵的想法……我只需要一种方法来转换点。
  • 我认为您的图像链接已损坏,我感觉缺少该图像是为什么我似乎缺少有关如何从两个单独的集合中导出一组非线性方程的部分的对应点。如果您能详细说明如何推导变换方程,我认为这将对我有很大帮助。
【解决方案2】:

您只需要 3 个点即可定义一个 3x3 变换矩阵。如果你有点 (0,0)、(0,1) 和 (1,0) 并通过矩阵 [a b c d e f 0 0 1] 变换它们,你将得到 (c,f), (b,e)和 (a,d)。

【讨论】:

  • 哦...我们有 6 个未知数,但是每对点有 2 个方程...所以 3 对将给我们 6 个方程。聪明!
【解决方案3】:

我认为您应该首先提供一个列表,例如 6 3 个点(对于 6 个未知数)以及转换前后的 X/Y 坐标。

那么比我更聪明的人应该将其放入一组线性方程中,然后将其提供给(比如说)Wolfram Alpha 进行求解。

AffineTransform 的 Java 文档顶部显示了需要如何设置矩阵:

[ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
[ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ]

去除大部分绒毛叶:

[ x']   [ m00x + m01y + m02 ]
[ y'] = [ m10x + m11y + m12 ]

然后你只需像这样设置一组 6 x 2 方程:

m00x + m01y + m02 - x' = 0
m10x + m11y + m12 - y' = 0

(在对之前/之后重复另外 2 个 x/y)

然后将它们扔给方程求解器。

【讨论】:

  • 这是对我的回答的简化,您只需删除 c3 和 c7 术语。但是,拼写所涉及的实际线性代数做得很好。你的“方程求解器”就是我的“高斯消元法”。
  • 谢谢!我很高兴看到我接近了。我想我在 30 年前完成了最后一次通用电气考试。从那时起,我很乐意让一个程序来做。很高兴看到 Mike 得到专业人士的照顾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 2017-12-12
相关资源
最近更新 更多