仿射 warp_matrix 内部是什么(如何分解)

Ant*_*ier 2 python opencv affinetransform cv2

我的问题与我的另一个问题有关。但在这里我试图更准确地理解使用 cv2.getAffineTransform 获得的 warp_matrix 的组成。我在找到了如何分解仿射变换矩阵,尤其是如何获得旋转角度

但是当使用OpenCV Doc 中的示例时,我获得了两个不同的旋转角度。

编码 :

import cv2
import numpy as np

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1,pts2)

theta0=np.degrees(np.arctan(-M[0,1]/M[0,0]))
theta1=np.degrees(np.arctan(M[1,0]/M[1,1]))

print(theta0)
print(theta1)
Run Code Online (Sandbox Code Playgroud)

生产 :

-25.3461759419
-18.4349488229
Run Code Online (Sandbox Code Playgroud)

alk*_*asm 6

相似变换(由缩放、旋转和平移的组合表示)是一个子集仿射变换的。仿射变换是任意的 2x3 矩阵,因此不必分解为单独的缩放、旋转和变换矩阵。

如果您不想使用仿射变换而是使用相似变换来进行这种分解,那么您将需要使用不同的函数来计算相似变换而不是仿射。

如果您使用的是 OpenCV 3.2.0+(也包括 4.0+),那么您可以使用cv2.estimateAffinePartial2D()(docs)。如果您使用的是以前的版本,则可以使用cv2.estimateRigidTransform()(docs)

从文档开始estimateAffinePartial2D(),估计的变换矩阵是

cos(?) * s   -sin(?) * s    t_x
sin(?) * s    cos(?) * s    t_y
Run Code Online (Sandbox Code Playgroud)

哪里?是旋转角度,s比例因子和t_xt_y分别是 x、y 轴的平移。

此处的结果可以根据您链接的答案进行分解。

cos(?) * s   -sin(?) * s    t_x
sin(?) * s    cos(?) * s    t_y
Run Code Online (Sandbox Code Playgroud)

您甚至可以在这里看到前两列的对角线显然是相关的,因为它们应该用于旋转,但只是要仔细检查:

>>> M, inliers = cv2.estimateAffinePartial2D(pts1, pts2)
>>> M
array([[  1.26666667,   0.33333333, -70.        ],
       [ -0.33333333,   1.26666667,  53.33333333]])
Run Code Online (Sandbox Code Playgroud)

请注意,您链接答案引用了不同问题的另一个答案。与我们在这里得到的矩阵和那里讨论的矩阵略有不同——在上面的版本中只有一个比例因子s,但在链接的版本中,有两个比例因子,s_xs_y。这有效地留下了五个自由度,即变量

s_x, s_y, ?, t_x, t_y
Run Code Online (Sandbox Code Playgroud)

相似变换有四个自由度,完全仿射变换有六个。我其实不知道五自由度的类型是不是常用的;我还没有在我读过的图像拼接/摄影测量文献中看到它讨论过(尽管从数学上讲,它当然仍然是仿射变换的有效子集)。我只是指出这一点,因为我的答案与您链接的答案之间存在差异,但实际上我认为您不会看到使用的那种类型的转换。