问题是你的矩阵是奇异的,这意味着它是不可逆的。既然你试图取它的逆,那就是一个问题。您链接到的线程是您问题的基本解决方案,但它并不是真正的最佳解决方案。您真正想要做的不仅仅是反转矩阵,而是解决最小二乘最小化问题,为可能存在噪声的数据找到最佳仿射变换矩阵。这样做的方法如下:
import numpy as np
primary = np.array([[40., 1160., 0.],
[40., 40., 0.],
[260., 40., 0.],
[260., 1160., 0.]])
secondary = np.array([[610., 560., 0.],
[610., -560., 0.],
[390., -560., 0.],
[390., 560., 0.]])
# Pad the data with ones, so that our transformation can do translations too
n = primary.shape[0]
pad = lambda x: np.hstack([x, np.ones((x.shape[0], 1))])
unpad = lambda x: x[:,:-1]
X = pad(primary)
Y = pad(secondary)
# Solve the least squares problem X * A = Y
# to find our transformation matrix A
A, res, rank, s = np.linalg.lstsq(X, Y)
transform = lambda x: unpad(np.dot(pad(x), A))
print "Target:"
print secondary
print "Result:"
print transform(primary)
print "Max error:", np.abs(secondary - transform(primary)).max()
原始矩阵是奇异的原因是您的第三个坐标始终为零,因此无法知道该坐标上的变换应该是什么(零乘以任何值都为零,因此任何值都可以工作)。
打印的值A
告诉您最小二乘法发现的变换:
A[np.abs(A) < 1e-10] = 0 # set really small values to zero
print A
结果是
[[ -1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 0. 0.]
[ 650. -600. 0. 1.]]
这相当于x2 = -x1 + 650, y2 = y1 - 600, z2 = 0
where x1, y1, z1
是原始系统中的坐标,x2, y2, z2
是新系统中的坐标。正如您所看到的,最小二乘只是将与第三维相关的所有项设置为零,因为您的系统实际上是二维的。