La caméra pose d'estimation (OpenCV PnP)
Je suis en train d'essayer d'obtenir une pose estimation à partir d'une image de quatre fiducials connus avec des positions mondiales à l'aide de ma webcam.
J'ai vérifié de nombreuses stackexchange questions et quelques papiers et je n'arrive pas à obtenir une solution correcte. Les numéros de poste, je ne sors sont reproductibles, mais en aucune façon linéairement proportionnelle au mouvement de la caméra. Pour info, je suis en utilisant C++, OpenCV 2.1.
ce lien est sur la photo mes systèmes de coordonnées et les données de test utilisés ci-dessous.
% Input to solvePnP():
imagePoints = [ 481, 831; % [x, y] format
520, 504;
1114, 828;
1106, 507]
objectPoints = [0.11, 1.15, 0; % [x, y, z] format
0.11, 1.37, 0;
0.40, 1.15, 0;
0.40, 1.37, 0]
% camera intrinsics for Logitech C910
cameraMat = [1913.71011, 0.00000, 1311.03556;
0.00000, 1909.60756, 953.81594;
0.00000, 0.00000, 1.00000]
distCoeffs = [0, 0, 0, 0, 0]
% output of solvePnP():
tVec = [-0.3515;
0.8928;
0.1997]
rVec = [2.5279;
-0.09793;
0.2050]
% using Rodrigues to convert back to rotation matrix:
rMat = [0.9853, -0.1159, 0.1248;
-0.0242, -0.8206, -0.5708;
0.1686, 0.5594, -0.8114]
Jusqu'à présent, peut-on voir rien de mal avec ces chiffres? Je vous serais reconnaissant si quelqu'un pouvait vérifier, par exemple, dans MatLAB (code ci-dessus est m-fichier de l'environnement).
À partir de ce point, je ne suis pas certain de la façon d'obtenir le mondial de pose de la rMat et tVec.
De ce que j'ai lu dans cette question, pour obtenir la pose de la rMat et tVec est tout simplement:
position = transpose(rMat) * tVec % matrix multiplication
Cependant je soupçonne d'autres sources que j'ai lu il n'est pas aussi simple que cela.
Pour obtenir la position de la caméra dans le monde réel les coordonnées, que dois-je faire?
Comme je ne suis pas sûr si c'est un problème de mise en œuvre (cependant plus probable une théorie de problème) je voudrais que quelqu'un qui a utilisé le solvePnP fonction avec succès dans OpenCV pour répondre à cette question, bien que toutes les idées sont les bienvenue aussi!
Je vous remercie beaucoup pour votre temps.
OriginalL'auteur Gouda | 2013-04-28
Vous devez vous connecter pour publier un commentaire.
J'ai résolu ce problème il y a un moment, toutes mes excuses pour l'année de retard.
Dans le python OpenCV 2.1 j'ai été en utilisant, et la nouvelle version 3.0.0-dev, j'ai vérifié que, pour obtenir de la pose de la caméra dans le cadre global, vous devez:
Maintenant pos est la position de la caméra exprimé dans le cadre global (le même cadre de la objectPoints sont exprimés dans).
R est une attitude matrice de DCM, ce qui est une bonne forme de stocker l'attitude.
Si vous avez besoin d'angles d'Euler ensuite, vous pouvez convertir le DCM à angles d'Euler donné un XYZ séquence de rotation à l'aide de:
Que voulez-vous dire par "il n'a pas une X-Y-Z du système de coordonnées'? Il est le
RQdecomp3x3
fonction OpenCV 3.0. J'ai trouvé qu'il me donne les mêmes résultats que la conversion l'on trouve parfois sur internet (par exemple ici nghiaho.com/?page_id=846):theta_x = atan2(R.at<double>(2,1), R.at<double>(2,2)); theta_y = atan2(-R.at<double>(2,0), sqrt(pow(R.at<double>(2,1), 2) + pow(R.at<double>(2,2),2))); theta_z = atan2(R.at<double>(1,0), R.at<double>(0,0));
Je ment que le système de coordonnées de opencv diffère de la norme de système de coordonnées pour les avions et d'autres domaines.
Merci d'avoir posé la question, et pour répondre: toutes les Api et les docs donner s*Pc=K[R|T]Pw, mais nulle part en ligne vous indique camera_pose = -(inv(R))*T qui est ce que vous voulez!
OriginalL'auteur Gouda
Si tu veux dire avec mondiale poser un 4x4 de la caméra pose de la matrice, qui peut être utilisé en OpenGL, je le fais de cette façon
Je pense qu'en le feuilletant le système de coordonnées est nécessaire, parce que OpenCV et OpenGL/VTK/etc. l'utilisation de différents systèmes de coordonnées, comme l'illustre cette image OpenGL et OpenCV Systèmes de Coordonnées
Bien, cela fonctionne de cette façon, mais quelqu'un a peut-être une meilleure explication.
OriginalL'auteur Adrian Schneider
position de la caméra serait { - transposition( r ) * t } . C'est tout.
Et vous avez tout fait correctement, sauf , cv::solvePnp donne (4 x 1) vecteur pour la traduction, si je me souviens bien , vous devez diviser x , y , z avec le w coordonner.
Je suis d'accord mais pour une raison ou une autre,- T*R. t() est celui qui le fait fonctionner.
OriginalL'auteur Avanindra Singh