J'essaie de récupérer des vecteurs de traduction et de rotation à partir d'une matrice fondamentale calculée. J'utilise OpenCV et l'approche générale est de Wikipédia. Mon code est comme ça:
//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;
À la fin, j'essaie de comparer la rotation estimée à celle que j'ai calculée à l'aide de l'échiquier figurant dans chaque image (je prévois d'obtenir les paramètres extrinsèques sans l'échiquier). Par exemple je reçois ceci:
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]
Si clairement qu'il semble y avoir un problème, je ne peux tout simplement pas comprendre ce que cela pourrait être.
EDIT: Voici les résultats que j'ai obtenus avec le vt non transposé (visiblement d'une autre scène):
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]
Voici ma matrice de caméra calculée, l'erreur était assez faible (environ 0,17 ...).
[1699.001342509651, 0, 834.2587265398068;
0, 1696.645251354618, 607.1292618175946;
0, 0, 1]
Voici les résultats obtenus lors de la reprojection d'un cube ... Caméra 0, le cube est aligné sur l'axe, la rotation et la translation sont (0, 0, 0). image http://imageshack.us/a/img802/5292/bildschirmfoto20130110u.png
et l’autre, avec les épilines des points de la première image. image http://imageshack.us/a/img546/189/bildschirmfoto20130110uy.png
S'il vous plaît jeter un oeil à ce lien:
http://isit.u-clermont1.fr/~ab/Classes/DIKU-3DCV2/Handouts/Lecture16.pdf .
Reportez-vous à la page 2. Il existe deux possibilités pour R. La première est UWVT et la seconde est UWTVT. Vous avez utilisé le second. Essayez le premier.
L'algorithme en 8 points est la méthode la plus simple de calcul de la matrice fondamentale, mais si vous prenez des précautions, vous pouvez bien l'exécuter. La clé pour obtenir de bons résultats est une normalisation minutieuse des données d’entrée avant de construire les équations à résoudre. Beaucoup d'algorithmes peuvent le faire. La coordonnée du point des pixels doit être remplacée par celle de la caméra, procédez comme suit:
Mat E = A.t() * F * A;
Cependant, cette hypothèse n'est pas exacte. Si la matrice d'étalonnage de la caméra K est connue, vous pouvez alors appliquer l'inverse du point x pour obtenir le point exprimé en coordonnées normalisées.
X_{norm}= K.inv()*X_{pix}
où X_{pix}(2)
, z est égal à 1.
Dans le cas de la 8PA, une simple transformation de points améliore et donc la stabilité des résultats. La normalisation suggérée est une translation et une mise à l'échelle de chaque image de sorte que le centre de gravité des points de référence soit à l'origine des coordonnées et que la distance RMS des points d'origine soit égale à \sqrt{2}
. Notez qu'il est recommandé d'appliquer la condition de singularité avant la dénormalisation.
Référence: cochez si: vous êtes toujours intéressé