OpenCv warpPerspective 元素的单应性含义

use*_*234 4 opencv homogenous-transformation

我有一个关于投影变换矩阵中元素的含义的问题,例如在OpenCv warpPerspective.

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

A11 A12 A13
A21 A22 A23
A31 A32  1
Run Code Online (Sandbox Code Playgroud)

我稍微处理了这些值,这意味着所有其他元素都有固定的数字。意义:

 1   0   0 
 0   1   0
A31 A32  1
Run Code Online (Sandbox Code Playgroud)

只有投射元素。

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

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

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

alk*_*asm 8

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)
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

我将此应用于从牛津视觉几何组拍摄的图像上。

米20

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

米20米10

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @I.Newton 如果您只编写一系列图像(在循环中创建一个索引变量,例如 `i`,并将该索引添加到文件名中),您可以使用任意数量的工具将每个帧组合成一个 `gif`。我使用 ImageMagick,这是一个非常棒的用于图像处理的 Unix 命令行工具。调整图像的大小,使它们足够小,然后像 Stack 上的普通图像一样放置它们! (2认同)