OpenCv warp单应性元素的透视意义

Posted

技术标签:

【中文标题】OpenCv warp单应性元素的透视意义【英文标题】:OpenCv warpPerspective meaning of elements of homography 【发布时间】:2017-08-18 17:06:15 【问题描述】:

我对投影变换矩阵中元素的含义有疑问,例如在OpenCv warpPerspective 使用的单应性中。

我知道仿射变换的基本知识,但在这里我对射影变换更感兴趣,这意味着在下面显示的矩阵中元素 A31A32

A11 A12 A13
A21 A22 A23
A31 A32  1

我稍微玩弄了一些值,这意味着所有其他元素都有一个固定的数字。含义:

 1   0   0 
 0   1   0
A31 A32  1

只有投影元素。

但是究竟是什么导致了元素 A31 和 A32 ?像 A13 和 A23 负责水平和垂直平移。

这两个元素有简单的解释吗?就像具有正值意味着 ....,具有负值意味着 ....某某像那样。

希望任何人都可以帮助我。

【问题讨论】:

【参考方案1】:

Newton 的描述是正确的,但实际查看转换以了解正在发生的事情以及它们如何与转换矩阵中的其他值一起工作以更有意义可能会有所帮助。我将给出一些带有动画的 python/OpenCV 示例来展示这些值的作用。

import numpy as np
import cv2
img = cv2.imread('img1.png')
h, w = img.shape[:2]

# initializations
max_m20 = 2e-3
nsteps = 50
M = np.eye(3)

所以在这里我将转换矩阵设置为恒等式(无转换)。我们希望看到在变换矩阵M 中更改 (2, 0) 处的元素的效果,因此我们将通过在0max_m20 之间线性间隔的nsteps 循环来制作动画。

for m20 in np.linspace(0, max_m20, nsteps):
    M[2, 0] = m20
    warped = cv2.warpPerspective(img, M, (w, h))
    cv2.imshow('warped', warped)
    k = cv2.waitKey(1)
    if k == ord('q') & 0xFF:
        break

我将此应用于从Oxford's Visual Geometry Group 拍摄的图像。

确实,我们可以看到这类似于围绕与图像左边缘对齐的点旋转相机,或围绕轴旋转图像本身。但是, 与此略有不同。请注意,顶部边缘始终保持在顶部,这有点奇怪。我们不会像上面那样绕轴旋转,而是想象顶部边缘也会开始下降到右侧边缘。像这样:

好吧,如果您正在考虑转换,获得这种转换的一种简单方法是采用上面的转换,并添加一些倾斜失真,以便在推动右下角时将右上侧向下推向上。实际上,这正是该视图的创建方式:

M = np.eye(3)
max_m20 = 2e-3
max_m10 = 0.6
for m20, m10 in zip(np.linspace(0, max_m20, nsteps), np.linspace(0, max_m10, nsteps)):
    M[2, 0] = m20
    M[1, 0] = m10
    warped = cv2.warpPerspective(img, M, (w, h))
    cv2.imshow('warped', warped)
    k = cv2.waitKey(1)
    if k == ord('q') & 0xFF:
        break

因此,在 IMO 中,考虑这些矩阵中的透视图的正确方法是,将倾斜条目和最后一行放在一起。这些是单应矩阵中实际修改角度的两个位置*;否则,它只是旋转、缩放和平移——所有这些都是角度保持。

*注意:实际上,角度可以通过另一种我没有提到的方式来改变。仿射变换允许非均匀缩放,这意味着您可以拉伸形状的宽度而不是高度,反之亦然,这也会改变角度。想象一下,如果你有一个三角形并且只拉伸它的宽度;角度会改变。所以事实证明,非均匀缩放(即当变换矩阵的第一个元素和中间元素是不同的值时)可以修改角度,除了透视变化和剪切失真。

请注意,在这些示例中,同样适用于最后一行中的第二个条目以及另一个倾斜位置;唯一的区别是它发生在顶部而不是左侧。这两种情况下的负值类似于沿该轴将平面旋转到而不是远离相机。

【讨论】:

太好了!即使我尝试添加 gif,但不知道如何添加。为 gif +1。 @I.Newton 如果您只是编写一系列图像(在循环中创建一个索引变量,如i 并将该索引添加到文件名中),您可以使用任意数量的工具来组合每一帧到一个gif。我使用 ImageMagick,一个非常棒的用于图像处理的 unix 命令行工具。调整图像大小,使其足够小,然后像普通图像一样将它们放到 Stack 上! 谢谢,我下次试试。【参考方案2】:

单应矩阵的 3x1 ,3x2 元素改变了图像的平面。这就是仿射矩阵和单应矩阵之间的区别。例如考虑一下 - A31 沿左边缘改变图像的平面。就像将您的图像粘贴到像旗帜一样的棍子上并旋转。正极是顺时针,负极是反向。另一个元素从顶部边缘执行相同的操作。但他们一起为你的形象设定了一个平面。这是我能说的最简单的方式。

【讨论】:

以上是关于OpenCv warp单应性元素的透视意义的主要内容,如果未能解决你的问题,请参考以下文章

如何计算两次透视变换后的结果?

OpenCV中的特征匹配+单应性以查找对象

OpenCV仿射变换+投射变换+单应性矩阵

OpenCV单应性矩阵发现参数估算方法详解

带有特征检测和单应性的 OpenCV 对象检测

单应性?在某些视图中处理丢失棋盘角的 OpenCV 方法?