OpenCv warpPerspective的homography元素含义

4

我有一个关于投影变换矩阵元素含义的问题,例如在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负责水平和垂直平移一样。

这两个元素有简单的解释吗?比如说,正值表示......,负值表示......之类的。希望能有这样的解释。

希望有人可以帮助我。

2个回答

8

牛顿的描述是正确的,但实际上看到转换可能更有帮助,以便理解正在发生的事情,以及它们如何与变换矩阵中的其他值一起工作,使更有意义。我将给出一些带有动画的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

我在从牛津大学视觉几何组获取的图像上应用了这个技术。

m20

我们可以看到,这与围绕与图像左边缘对齐的点旋转相似,或者将图像本身围绕轴旋转。然而,它确实有一些不同。请注意,顶部边缘始终沿着顶部移动,这有点奇怪。如果我们像上面那样围绕轴旋转,我们会想象顶部边缘也会开始下降到右侧边缘。就像这样:

m20m10

好吧,如果你考虑变换,一种简单的方法是采用上述变换,并添加一些倾斜畸变,使右上侧被向下推动,同时底部右侧角被向上推动。这正是创建此视图的确切方式:

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

因此,在这些矩阵中,正确思考角度的方式是将斜向条目和最后一行放在一起。这是单应矩阵中实际修改角度的两个地方;否则,它只是旋转、缩放和平移——所有这些都是保持角度不变的操作。
注意:实际上,还有一种我没有提到的方法可以改变角度。仿射变换允许非均匀缩放,这意味着你可以在宽度上拉伸形状而不拉伸高度,反之亦然,这也会改变角度。想象一下如果你有一个三角形,只在宽度上拉伸;那么角度会改变。因此,非均匀缩放(即变换矩阵的第一个和中间元素是不同值)除了透视变换和倾斜扭曲外,还可以改变角度。
请注意,在这些示例中,最后一行的第二个条目与其他倾斜位置相同;唯一的区别是它发生在顶部而不是左侧。在这两种情况下的负值类似于沿该轴旋转平面以朝向相机,而不是远离相机。

太好了!我也曾经尝试添加gif但不知道怎么弄。给这个gif点赞。 - I.Newton
2
@I.Newton 如果你只是编写一系列图像(在循环中创建一个索引变量,如 i,并将该索引添加到文件名中),则可以使用任意数量的工具将每个帧组合为 gif。我使用 ImageMagick,这是一个非常棒的用于图像处理的 Unix 命令行工具。调整图像大小,使它们足够小,并像正常图像一样拖放它们到 Stack! - alkasm
谢谢,我下次会尝试。 - I.Newton

4

Homography矩阵的3x1和3x2元素可以改变图像的平面,这就是仿射矩阵和Homography矩阵之间的区别。例如,考虑这个例子- A31沿着左边缘改变了图像的平面。这就像把你的图像像旗帜一样粘在一根棍子上并旋转。正数是顺时针,负数是逆时针。另一个元素从顶部边缘做同样的事情。但是,它们一起为您的图像设置了一个平面。这是我能想到的最简单的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接