仿射里面是什么(如何分解)warp_matrix
What is inside (how to decompose) an affine warp_matrix
我的问题与我 asked 的另一个问题有关。但在这里我试图更准确地理解用 cv2.getAffineTransform 获得的 warp_matrix 的组成。
我在 this 中找到了如何分解仿射变换矩阵,尤其是如何获得旋转角度
但是当使用 the 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)
生产:
-25.3461759419
-18.4349488229
相似变换(由缩放、旋转和平移的组合表示)是仿射变换的子集。仿射变换是任意 2x3 矩阵,因此不必分解为单独的缩放、旋转和变换矩阵。
如果您不想使用仿射变换而是使用相似变换来执行此分解,那么您将需要使用不同的函数来计算相似变换而不是仿射。
如果您使用的是 OpenCV 3.2.0+(也包括 4.0+),那么您可以使用 cv2.estimateAffinePartial2D()
(docs). If you're on a previous version, you can use cv2.estimateRigidTransform()
(docs).
根据estimateAffinePartial2D()
上的文档,估计的变换矩阵是
cos(θ) * s -sin(θ) * s t_x
sin(θ) * s cos(θ) * s t_y
其中θ
是旋转角度,s
是比例因子,t_x
、t_y
分别是x、y轴的平移。
这里的结果可以按照你链接的答案分解。
>>> M, inliers = cv2.estimateAffinePartial2D(pts1, pts2)
>>> M
array([[ 1.26666667, 0.33333333, -70. ],
[ -0.33333333, 1.26666667, 53.33333333]])
你甚至可以在这里看到前两列的对角线显然是相关的,因为它们应该是旋转的,但只是仔细检查一下:
>>> theta0 = np.degrees(np.arctan2(-M[0,1], M[0,0]))
>>> theta1 = np.degrees(np.arctan2(M[1,0], M[1,1]))
>>> print(theta0)
-14.7435628365
>>> print(theta1)
-14.7435628365
请注意 answer you linked references another answer 来自不同的问题。我们在这里得到的矩阵和那里讨论的矩阵略有不同---在上面的版本中只有一个比例因子 s
,但在链接的版本中,有两个比例因子,s_x
和 s_y
。这有效地留下 5 个自由度,即变量
s_x, s_y, θ, t_x, t_y
相似变换有 4 个自由度,而全仿射变换有 6 个自由度。我实际上不知道具有五个自由度的类型是否是常用的;我没有在我读过的图像 stitching/photogrammetry 文献中看到它的讨论(尽管在数学上它当然仍然是仿射变换的有效子集)。我只是指出这一点,因为这是我的答案与您链接的答案之间的差异,但实际上我认为您不会看到使用的那种类型的转换。
我的问题与我 asked 的另一个问题有关。但在这里我试图更准确地理解用 cv2.getAffineTransform 获得的 warp_matrix 的组成。 我在 this 中找到了如何分解仿射变换矩阵,尤其是如何获得旋转角度
但是当使用 the 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)
生产:
-25.3461759419
-18.4349488229
相似变换(由缩放、旋转和平移的组合表示)是仿射变换的子集。仿射变换是任意 2x3 矩阵,因此不必分解为单独的缩放、旋转和变换矩阵。
如果您不想使用仿射变换而是使用相似变换来执行此分解,那么您将需要使用不同的函数来计算相似变换而不是仿射。
如果您使用的是 OpenCV 3.2.0+(也包括 4.0+),那么您可以使用 cv2.estimateAffinePartial2D()
(docs). If you're on a previous version, you can use cv2.estimateRigidTransform()
(docs).
根据estimateAffinePartial2D()
上的文档,估计的变换矩阵是
cos(θ) * s -sin(θ) * s t_x
sin(θ) * s cos(θ) * s t_y
其中θ
是旋转角度,s
是比例因子,t_x
、t_y
分别是x、y轴的平移。
这里的结果可以按照你链接的答案分解。
>>> M, inliers = cv2.estimateAffinePartial2D(pts1, pts2)
>>> M
array([[ 1.26666667, 0.33333333, -70. ],
[ -0.33333333, 1.26666667, 53.33333333]])
你甚至可以在这里看到前两列的对角线显然是相关的,因为它们应该是旋转的,但只是仔细检查一下:
>>> theta0 = np.degrees(np.arctan2(-M[0,1], M[0,0]))
>>> theta1 = np.degrees(np.arctan2(M[1,0], M[1,1]))
>>> print(theta0)
-14.7435628365
>>> print(theta1)
-14.7435628365
请注意 answer you linked references another answer 来自不同的问题。我们在这里得到的矩阵和那里讨论的矩阵略有不同---在上面的版本中只有一个比例因子 s
,但在链接的版本中,有两个比例因子,s_x
和 s_y
。这有效地留下 5 个自由度,即变量
s_x, s_y, θ, t_x, t_y
相似变换有 4 个自由度,而全仿射变换有 6 个自由度。我实际上不知道具有五个自由度的类型是否是常用的;我没有在我读过的图像 stitching/photogrammetry 文献中看到它的讨论(尽管在数学上它当然仍然是仿射变换的有效子集)。我只是指出这一点,因为这是我的答案与您链接的答案之间的差异,但实际上我认为您不会看到使用的那种类型的转换。