2013-01-04 15 views
16

Sto cercando di recuperare i vettori di traslazione e rotazione da una matrice fondamentale calcolata. Io uso OpenCV e l'approccio generale è da Wikipedia. Il mio codice è simile a questo:Estrazione di traduzione e rotazione dalla matrice fondamentale

//Compute Essential Matrix 
Mat A = cameraMatrix(); //Computed using chessboard 
Mat F = fundamentalMatrix(); //Computed using matching keypoints 
Mat E = A.t() * F * A; 

//Perfrom SVD on E 
SVD decomp = SVD(E); 

//U 
Mat U = decomp.u; 

//S 
Mat S(3, 3, CV_64F, Scalar(0)); 
S.at<double>(0, 0) = decomp.w.at<double>(0, 0); 
S.at<double>(1, 1) = decomp.w.at<double>(0, 1); 
S.at<double>(2, 2) = decomp.w.at<double>(0, 2); 

//V 
Mat V = decomp.vt; //Needs to be decomp.vt.t(); (transpose once more) 

//W 
Mat W(3, 3, CV_64F, Scalar(0)); 
W.at<double>(0, 1) = -1; 
W.at<double>(1, 0) = 1; 
W.at<double>(2, 2) = 1; 

cout << "computed rotation: " << endl; 
cout << U * W.t() * V.t() << endl; 
cout << "real rotation:" << endl; 
Mat rot; 
Rodrigues(images[1].rvec - images[0].rvec, rot); //Difference between known rotations 
cout << rot << endl; 

Alla fine cerco di confrontare la rotazione stimato per quello che ho calcolata utilizzando la scacchiera, che è in ogni immagine (I piano per ottenere i parametri estrinseci senza la scacchiera). Per esempio ottengo questo:

computed rotation: 
[0.8543027125286542, -0.382437675069228, 0.352006107978011; 
    0.3969758209413922, 0.9172325022900715, 0.03308676972148356; 
    0.3355250705298953, -0.1114717965690797, -0.9354127247453767] 

real rotation: 
[0.9998572365450219, 0.01122579241510944, 0.01262886032882241; 
    -0.0114034800333517, 0.9998357441946927, 0.01408706050863871; 
    -0.01246864754818991, -0.01422906234781374, 0.9998210172891051] 

Così chiaramente sembra che ci sia un problema, non riesco proprio a capire cosa potrebbe essere.

EDIT: Ecco i risultati che ho ottenuto con il VT non trasposta (ovviamente da un'altra scena):

computed rotation: 
[0.8720599858028177, -0.1867080200550876, 0.4523842353671251; 
0.141182538980452, 0.9810442195058469, 0.1327393312518831; 
-0.4685924368239661, -0.05188790438313154, 0.8818893204535954] 
real rotation 
[0.8670861432556456, -0.427294988334106, 0.2560871201732064; 
0.4024551137989086, 0.9038194629873437, 0.1453969040329854; 
-0.2935838918455123, -0.02300806966752995, 0.9556563855167906] 

Ecco la mia matrice di macchina fotografica computerizzata, l'errore è stato piuttosto basso (circa 0,17 ...) .

[1699.001342509651, 0, 834.2587265398068; 
    0, 1696.645251354618, 607.1292618175946; 
    0, 0, 1] 

Ecco i risultati che ottengo quando si cerca di riproiettare un cubo ... Camera 0, il cubo è l'asse allineato, rotazione e traslazione sono (0, 0, 0). image http://imageshack.us/a/img802/5292/bildschirmfoto20130110u.png

e l'altro, con le epilinee dei punti nella prima immagine. image http://imageshack.us/a/img546/189/bildschirmfoto20130110uy.png

+2

'decomp.vt' è V trasposizione, non V.Cosa ottieni se dici 'U * W.t() * V'? – yiding

+0

Scusa la mia risposta in ritardo, grazie per la correzione. Ovviamente avevo dimenticato questo. Ho aggiornato la risposta con i nuovi risultati, purtroppo ancora non sembrano esattamente giusti. – Teris

+0

I coefficienti di distorsione calcolati dovrebbero essere anche moltiplicati nella matrice essenziale in qualche modo? – Teris

risposta

10

prega di dare un'occhiata a questo link:

http://isit.u-clermont1.fr/~ab/Classes/DIKU-3DCV2/Handouts/Lecture16.pdf.

riferimento a pagina 2. Ci sono due possibilità per R. Il primo è U W VT e il secondo è U WT VT. Hai usato il secondo. Prova il primo

+3

Grazie. Questo è esattamente quello che mi mancava. Posso anche raccomandare le fonti molto semplici e facili da comprendere del nuovo libro "Mastering OpenCV con progetti pratici di computer vision" https://github.com/MasteringOpenCV/code – Teris

+0

Grazie - non sapevo di quel libro. – user1993497

+1

Potete fornire un link che spiega come stabilire quale R è corretta? –

0

L'algoritmo a 8 punti è il metodo più semplice per calcolare la matrice fondamentale, ma se si presta attenzione è possibile eseguirlo bene. La chiave per ottenere i buoni risultati è un'attenta normalizzazione attenta dei dati di input prima di costruire le equazioni da risolvere. Molti algoritmi possono farlo. Pixel coordinate punto deve essere cambiato per le coordinate della telecamera, lo si fa in questa linea:

Mat E = A.t() * F * A;

Tuttavia questa ipotesi non è preciso. Se la matrice di calibrazione della fotocamera K è nota, è possibile applicare inverso al punto x per ottenere il punto espresso in coordinate normalizzate.

X_{norm}= K.inv()*X_{pix} dove X_{pix}(2), z è uguale 1.

Nel caso del 8PA, una semplice trasformazione di punti migliorano e quindi nella stabilità dei risultati. La normalizzazione suggerita è una traslazione e ridimensionamento di ogni immagine in modo che il centroide dei punti di riferimento sia all'origine delle coordinate e la distanza RMS dei punti dall'origine sia uguale a \sqrt{2}. Si noti che è consigliabile applicare la condizione di singolarità prima della denormalizzazione.

Riferimento: controllare se: you are still interested

Problemi correlati