Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jclosure/b98918f8b02a1a6c7fe760822acb07d2 to your computer and use it in GitHub Desktop.
Save jclosure/b98918f8b02a1a6c7fe760822acb07d2 to your computer and use it in GitHub Desktop.
Affine transformation of coordinate system using least squares to reduce error
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.]])
def least_squares_transform():
# 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[np.abs(A) < 1e-10] = 0 # set really small values to zero
print A
@jclosure
Copy link
Author

jclosure commented Sep 11, 2017

Target:

[[ 610.  560.    0.]
 [ 610. -560.    0.]
 [ 390. -560.    0.]
 [ 390.  560.    0.]]

Result:

[[ 610.  560.    0.]
 [ 610. -560.    0.]
 [ 390. -560.    0.]
 [ 390.  560.    0.]]

Max error:

1.13686837722e-12

A:

[[  -1.    0.    0.    0.]
 [   0.    1.    0.    0.]
 [   0.    0.    0.    0.]
 [ 650. -600.    0.    1.]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment