有没有人知道基于已知两个坐标系中一组确定点的标准算法来确定仿射变换矩阵?
有没有人知道基于已知两个坐标系中一组确定点的标准算法来确定仿射变换矩阵?
仿射变换使用2x3矩阵来表示。我们通过将二维输入(x y)扩展为三维向量(x y 1),然后在左侧乘以M来执行仿射变换M。
因此,如果我们有三个点(x1 y1) (x2 y2) (x3 y3)映射到(u1 v1) (u2 v2) (u3 v3),则我们有
[x1 x2 x3] [u1 u2 u3]
M [y1 y2 y3] = [v1 v2 v3].
[ 1 1 1]
你可以通过右侧乘以的逆矩阵来得到M
[x1 x2 x3]
[y1 y2 y3]
[ 1 1 1].
将一个2x3矩阵右乘一个3x3矩阵,可以得到我们想要的2x3矩阵。(实际上不需要完全求逆,但如果有矩阵求逆可用,则很容易使用。)
很容易适应其他维度。如果您有超过3个点,您可能需要进行最小二乘拟合。但这需要再次询问,并且会更加困难。
import numpy as np
# input data
ins = [[1, 1, 2], [2, 3, 0], [3, 2, -2], [-2, 2, 3]] # <- points
out = [[0, 2, 1], [1, 2, 2], [-2, -1, 6], [4, 1, -3]] # <- mapped to
# calculations
l = len(ins)
B = np.vstack([np.transpose(ins), np.ones(l)])
D = 1.0 / np.linalg.det(B)
entry = lambda r,d: np.linalg.det(np.delete(np.vstack([r, B]), (d+1), axis=0))
M = [[(-1)**i * D * entry(R, i) for i in range(l)] for R in np.transpose(out)]
A, t = np.hsplit(np.array(M), [l-1])
t = np.transpose(t)[0]
# output
print("Affine transformation matrix:\n", A)
print("Affine transformation translation vector:\n", t)
# unittests
print("TESTING:")
for p, P in zip(np.array(ins), np.array(out)):
image_p = np.dot(A, p) + t
result = "[OK]" if np.allclose(image_p, P) else "[ERROR]"
print(p, " mapped to: ", image_p, " ; expected: ", P, result)