仅六个点不足以唯一地确定仿射变换。但是,根据您之前在问题中提出的问题(在删除之前不久)以及你的评论 https://stackoverflow.com/questions/27546081/determining-transformation-matrix-from-six-points-in-python/27547597#comment43823906_27547597,看来您不仅仅是在寻找仿射变换,而是在寻找齐次仿射变换.
罗布约翰的回答 https://math.stackexchange.com/a/222170提供问题的解决方案。虽然它解决了一个有很多点的更一般的问题,但 6 个点的解决方案可以在答案的最底部找到。我将在这里以对程序员更友好的格式转录它:
import numpy as np
def recover_homogenous_affine_transformation(p, p_prime):
'''
Find the unique homogeneous affine transformation that
maps a set of 3 points to another set of 3 points in 3D
space:
p_prime == np.dot(p, R) + t
where `R` is an unknown rotation matrix, `t` is an unknown
translation vector, and `p` and `p_prime` are the original
and transformed set of points stored as row vectors:
p = np.array((p1, p2, p3))
p_prime = np.array((p1_prime, p2_prime, p3_prime))
The result of this function is an augmented 4-by-4
matrix `A` that represents this affine transformation:
np.column_stack((p_prime, (1, 1, 1))) == \
np.dot(np.column_stack((p, (1, 1, 1))), A)
Source: https://math.stackexchange.com/a/222170 (robjohn)
'''
# construct intermediate matrix
Q = p[1:] - p[0]
Q_prime = p_prime[1:] - p_prime[0]
# calculate rotation matrix
R = np.dot(np.linalg.inv(np.row_stack((Q, np.cross(*Q)))),
np.row_stack((Q_prime, np.cross(*Q_prime))))
# calculate translation vector
t = p_prime[0] - np.dot(p[0], R)
# calculate affine transformation matrix
return np.column_stack((np.row_stack((R, t)),
(0, 0, 0, 1)))
对于您的示例输入,这将恢复与您从 CAD 程序获得的矩阵完全相同的矩阵:
>>> recover_homogenous_affine_transformation(
np.array(((1.0,1.0,1.0),
(1.0,2.0,1.0),
(1.0,1.0,2.0))),
np.array(((2.4142135623730940, 5.732050807568877, 0.7320508075688767),
(2.7677669529663684, 6.665063509461097, 0.6650635094610956),
(2.7677669529663675, 5.665063509461096, 1.6650635094610962))))
array([[ 0.8660254 , -0.35355339, -0.35355339, 0. ],
[ 0.35355339, 0.9330127 , -0.0669873 , 0. ],
[ 0.35355339, -0.0669873 , 0.9330127 , 0. ],
[ 0.84108138, 5.21957879, 0.21957879, 1. ]])