2013-01-04 16 views
16

Ich versuche, Translations- und Rotationsvektoren aus einer berechneten fundamentalen Matrix abzurufen. Ich benutze OpenCV und der allgemeine Ansatz ist von Wikipedia. Mein Code ist wie folgt:Extrahieren von Translation und Rotation aus der Fundamentalmatrix

//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; 

Am Ende ich versuche, die geschätzte Rotation auf die vergleichen ich das Schachbrett berechnet unter Verwendung der in jedem Bild ist (ich plane, ohne das Schachbrett die extrinsischen Parameter zu erhalten). Zum Beispiel habe ich diese:

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] 

So klar es ein Problem zu sein scheint, kann ich einfach nicht herausfinden, was es sein könnte.

EDIT: Hier sind die Ergebnisse, die ich mit dem untransponiert vt bekam (offensichtlich aus einer anderen Szene):

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] 

Hier ist meine berechnete Kameramatrix, der Fehler war ziemlich niedrig (etwa 0,17 ...) .

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

Hier sind die Ergebnisse bekomme ich, wenn ein Würfel zu projizieren versuchen ... Kamera 0, der Würfel ist Achse ausgerichtet sind, Rotation und Translation (0, 0, 0). image http://imageshack.us/a/img802/5292/bildschirmfoto20130110u.png

und der andere, mit den Epilinen der Punkte im ersten Bild. image http://imageshack.us/a/img546/189/bildschirmfoto20130110uy.png

+2

'decomp.vt' V transponieren, nicht V.Was bekommst du, wenn du "U * W.t() * V" sagst? – yiding

+0

Entschuldigen Sie meine späte Antwort, danke für Ihre Korrektur. Ich hatte das offensichtlich vergessen. Ich habe die Antwort mit den neuen Ergebnissen aktualisiert, leider scheinen sie immer noch nicht richtig zu sein. – Teris

+0

Sollten die berechneten Verzerrungskoeffizienten auch irgendwie in die Essential Matrix multipliziert werden? – Teris

Antwort

10

Bitte nehmen Sie sich einen Blick auf diesen Link:

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

Siehe Seite 2. Es gibt zwei Möglichkeiten für R. Die erste U W VT und das zweite ist U WT VT. Du hast den zweiten benutzt. Probieren Sie den ersten.

+3

Danke. Genau das habe ich vermisst. Ich kann auch die sehr einfachen und leicht verständlichen Quellen des neuen Buches "Mastering OpenCV mit praktischen Computer Vision Projekten" https://github.com/MasteringOpenCV/code – Teris

+0

Vielen Dank - Ich wusste nicht über das Buch. – user1993497

+1

Können Sie einen Link angeben, der erklärt, wie R korrekt ist? –

0

Der 8-Punkt-Algorithmus ist die einfachste Methode zur Berechnung der Fundamentalmatrix, aber wenn man vorsichtig ist, kann man sie gut durchführen. Der Schlüssel, um die guten Ergebnisse zu erhalten, ist eine sorgfältige sorgfältige Normalisierung der Eingabedaten vor dem Konstruieren der zu lösenden Gleichungen. Viele Algorithmen können es tun. Pixel Punktkoordinate müssen Kamerakoordinaten geändert werden, tun Sie es in dieser Zeile:

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

jedoch diese Annahme nicht korrekt ist. Wenn die Kamerakalibrierungsmatrix K bekannt ist, dann können Sie eine Inverse auf den Punkt x anwenden, um den in den normalisierten Koordinaten ausgedrückten Punkt zu erhalten.

X_{norm}= K.inv()*X_{pix} wo X_{pix}(2), Z 1.

Im Fall des 8PA gleich ist, wird eine einfache Umwandlung der Punkte zu verbessern und damit die Stabilität der Ergebnisse. Die vorgeschlagene Normalisierung ist eine Translation und Skalierung jedes Bildes, so dass der Schwerpunkt der Bezugspunkte am Koordinatenursprung liegt und der Effektivabstand der Punkte vom Ursprung gleich \sqrt{2} ist. Beachten Sie, dass empfohlen wird, die Singularitätsbedingung vor der Denormalisierung durchzusetzen.

Referenz: überprüfen, ob: you are still interested

Verwandte Themen