2013-12-12 10 views
5

Ich habe gleiches Problem wie hier beschrieben: how to perform coordinates affine transformation using python?Wie man Koordinaten affine Transformation mit Python durchführen? Teil 2

Ich versuche Methode beschrieben zu verwenden, aber aus irgendeinem Grunde werde ich Fehlermeldungen. Änderungen, die ich am Code vorgenommen habe, sollten primäre System- und sekundäre Systempunkte ersetzen. Ich habe sekundäre Koordinatenpunkte mit verschiedenen origo erstellt. Im realen Fall, für den ich mich interessiere, wird dieses Thema einige Fehler bei der Koordinatenmessung haben.

primary_system1 = (40.0, 1160.0, 0.0) 
primary_system2 = (40.0, 40.0, 0.0) 
primary_system3 = (260.0, 40.0, 0.0) 
primary_system4 = (260.0, 1160.0, 0.0) 

secondary_system1 = (610.0, 560.0, 0.0) 
secondary_system2 = (610.0,-560.0, 0.0) 
secondary_system3 = (390.0, -560.0, 0.0) 
secondary_system4 = (390.0, 560.0, 0.0) 

Fehler ich aus, wenn folgenden ausgeführt wird.

*Traceback (most recent call last): 
    File "affine_try.py", line 57, in <module> 
    secondary_system3, secondary_system4) 
    File "affine_try.py", line 22, in solve_affine 
    A2 = y * x.I 
    File "/usr/lib/python2.7/dist-packages/numpy/matrixlib/defmatrix.py", line 850, in getI 
    return asmatrix(func(self)) 
    File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 445, in inv 
    return wrap(solve(a, identity(a.shape[0], dtype=a.dtype))) 
    File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 328, in solve 
    raise LinAlgError, 'Singular matrix' 
numpy.linalg.linalg.LinAlgError: Singular matrix* 

Was könnte das Problem sein?

Antwort

15

Das Problem ist, dass Ihre Matrix Singular ist, was bedeutet, dass sie nicht invertierbar ist. Da Sie versuchen, das Gegenteil davon zu nehmen, ist das ein Problem. Der Thread, den Sie verlinkt haben, ist eine grundlegende Lösung für Ihr Problem, aber es ist nicht wirklich die beste Lösung. Statt nur die Matrix zu invertieren, wollen Sie eigentlich ein Minimierungsproblem der kleinsten Quadrate lösen, um die optimale affine Transformationsmatrix für Ihre möglicherweise verrauschten Daten zu finden. Hier ist, wie Sie das tun würde:

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() 

Der Grund, dass Ihre ursprüngliche Matrix singulär war, ist, dass Ihre dritte Koordinate immer Null ist, so gibt es keine Möglichkeit zu sagen, was die auf die Transformation koordinieren soll (null mal alles gibt Null, also würde jeder Wert funktionieren).

den Wert A Drucken teilt Ihnen die Transformation, die der kleinsten Quadrate gefunden hat:

A[np.abs(A) < 1e-10] = 0 # set really small values to zero 
print A 

Ergebnisse in

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

, die zu x2 = -x1 + 650, y2 = y1 - 600, z2 = 0 äquivalent ist, wo x1, y1, z1 die Koordinaten in Ihrem ursprünglichen System sind und x2, y2, z2 sind die Koordinaten in Ihrem neuen System. Wie Sie sehen können, setzen die kleinsten Quadrate alle Terme der dritten Dimension auf Null, da Ihr System wirklich zweidimensional ist.

Verwandte Themen