Comment utiliser correctement cv::triangulatePoints()
Je suis en train de recouper certains points avec OpenCV et j'ai trouvé ce cv::triangulatePoints()
fonction. Le problème est qu'il n'y a presque pas de documentation ou des exemples.
J'ai quelques doutes à ce sujet.
-
Quelle méthode faut-il utiliser?
J'ai une petite recherche sur les triangulations et il y a plusieurs méthodes (Linéaire, Linéaire LS, eigen, itératif LS, itératif propres,...) mais je ne trouve pas celui qui est de l'aide dans OpenCV. -
Comment devrais-je l'utiliser? Il semble que comme entrée, il a besoin d'une matrice de projection et 3xN homogène 2D points. Je les ai définis comme
std::vector<cv::Point3d> pnts
, mais, comme résultat, il a besoin de 4xN tableaux et évidemment, je ne peux pas créer unestd::vector<cv::Point4d>
car il n'existe pas, alors comment dois-je définir le vecteur de sortie?
Pour la deuxième question j'ai essayé: cv::Mat pnts3D(4,N,CV_64F);
et cv::Mat pnts3d;
, ni semble fonctionner (elle lève une exception).
- Avez-vous regarder sur OpenCV documentation site web?
- en effet je l'ai fait, mais que la documentation ne permet pas de résoudre à aucune de mes questions!
- vérifier ceci.
- vérifié et testé déjà :D. je me suis préparé! Ce code n'est pas tout à fait correct. Dans la fonction InterativeLinearLStraingulation() les itérations toujours les sauts à la deuxième fois, parce que les variables u,u1,P et P1 ne sont pas mis à jour, en faisant la condition pour être vrai et de briser la boucle. Je suis triying de lire le livre de l'origine et de corriger le code, mais il n'est pas simple :S
- aussi vérifié le résultat sans itération (cela devrait fonctionner) mais il semble que cela ne fonctionne pas. Les résultats que j'obtiens ne sont pas fous, mais veillez à ne pas les corriger.
- Lire la source pour plus d'info: opencv\modules\calib3d\src\triangulate.cpp
Vous devez vous connecter pour publier un commentaire.
1.- La méthode utilisée est la méthode des moindres Carrés. Il existe des algorithmes plus complexes que celui-ci. Là encore, il est l'un des plus communs, comme les autres méthodes peut échouer dans certains cas (c'est à dire quelques autres échoue si les points sont sur un plan ou sur l'infini).
La méthode peut être trouvée dans de Vue Multiples sur la Géométrie de la Vision par Ordinateur par Richard Hartley et Andrew Zisserman (p312)
2.-L'utilisation:
Remplir le 2 chanel point de Matrices avec les points dans les images.
cam0
etcam1
sontMat3x4
caméra matrices (intrinsèques et extrinsèques des paramètres). Vous pouvez construire en multipliant*RT, où A est le paramètre intrinsèque de la matrice et RT la rotation de la traduction 3x4 pose de la matrice.NOTE:
pnts3D
doit être un 4 canaux 1xNcv::Mat
lorsqu'il est défini, déclenche une exception si pas, mais le résultat est uncv::Mat(4,N,cv_64FC1)
de la matrice. Vraiment déroutant, mais c'est la seule façon que je n'ai pas encore eu une exception.Mise à JOUR: à partir de la version 3.0 ou peut-être plus tôt, ce n'est plus vrai, et
pnts3D
peut également être de typeMat(4,N,CV_64FC1)
ou peut être entièrement vides (comme d'habitude, il est créé à l'intérieur de la fonction).Mat pnts3D(4, N, CV_64FC1)
fonctionne également.Un petit plus pour @Ander Biguri de réponse. Vous devriez obtenir votre image des points de non-
undistort
ed de l'image, et d'invoquerundistortPoints()
sur lecam0pnts
etcam1pnts
, parce quecv::triangulatePoints
attend de la 2D des points en coordonnées normalisées (indépendant de la caméra) etcam0
etcam1
devrait être seulement [R|t^T] matricies vous n'avez pas besoin de plusieurs avec Un.undistortPoints()
au lieu deundistort()
sur l'image, puis vous n'avez pas besoin d'A.Grâce à Ander Biguri! Sa réponse m'a beaucoup aidé. Mais je préfère toujours l'alternative avec std::vector, j'ai édité solution:
Donc, vous avez juste besoin de faire emplace_back dans les points. Principal avantage: vous n'avez pas besoin de connaître la taille
N
avant de commencer à les remplir. Malheureusement, il n'existe pas de cv::Point4f, donc pnts3D doit être un cv::Mat...J'ai essayé de cv::triangulatePoints, mais de toute façon il calcule les ordures. J'ai été forcé de mettre en œuvre un linéaire de la méthode de triangulation manuellement, ce qui renvoie une 4x1 matrice pour la triangulation de points 3D:
les paramètres d'entrée sont deux 3x4 caméra matrices de projection et un correspondant gauche/droite pixel paire (x,y,w).
Vous pouvez également utiliser la méthode de Hartley & Zisserman mis en place ici: http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/