2015-02-23 1 views
0

Je souhaite trouver la pose de l'objet en fonction des correspondances 3D-2D en utilisant cv :: solvePnPRansac. Mes correspondances peuvent avoir des valeurs aberrantes, donc je ne veux pas utiliser cv :: solvePnP. J'ai utilisé les correspondances 3D-2D d'un instantané pris d'une caméra en opengl. Donc, après le rétroprojection, je trouve que la matrice de rotation retournée après avoir utilisé solvePnP est correcte. Mais quand j'utilise solvePnPRansac, j'obtiens une matrice d'identité et un vecteur de traduction zéro. S'il vous plaît aider! J'ai utilisé le code suivant. Merci d'avance !cv :: solvePnPRansac renvoie la matrice d'identité

// Parameters to solvePnP 
Mat camera_mat(3, 3, CV_64FC1); 
Mat distCoeffs(4, 1, CV_64FC1); 
Mat rvec(3, 1, CV_64FC1); 
Mat tvec(3, 1, CV_64FC1); 
Mat d(3, 3, CV_64FC1); 

vector<Point3f> list_points3d_model_match; 
vector<Point2f> list_points2d_scene_match; 

while(map >> u >> v >> x >> y >> z) 
{ 
    Point2f ip = Point2f(u, v); 
    Point3f sp = Point3f(x, y, z); 

    // cout << x << " " << y << " " << z << endl; 
    list_points3d_model_match.push_back(sp); 
    list_points2d_scene_match.push_back(ip); 
} 

camera_mat.at<double>(0, 0) = 600; 
camera_mat.at<double>(1, 1) = 600; 
camera_mat.at<double>(0, 2) = WIDTH/2; 
camera_mat.at<double>(1, 0) = HEIGHT/2; 
camera_mat.at<double>(3, 3) = 1; 

// solvePnP(list_points3d_model_match, list_points2d_scene_match, camera_mat, distCoeffs, rvec, tvec, 
    //     useExtrinsicGuess, CV_ITERATIVE); 

tvec.at<float>(0) = 0; 
tvec.at<float>(1) = 0; 
tvec.at<float>(2) = 2; 

d.at<float>(0, 0) = 1; 
d.at<float>(1, 2) = -1; 
d.at<float>(2, 1) = 1; 

Rodrigues(d, rvec); 

solvePnPRansac(list_points3d_model_match, list_points2d_scene_match, camera_mat, distCoeffs, rvec, tvec, false, CV_ITERATIVE); 

Rodrigues(rvec, d); 

double* _r = d.ptr<double>(); 
printf("rotation mat: \n %.3f %.3f %.3f\n%.3f %.3f %.3f\n%.3f %.3f %.3f\n", 
    _r[0],_r[1],_r[2],_r[3],_r[4],_r[5],_r[6],_r[7],_r[8]); 
} 

cout << "translation vec:\n" << tvec << endl; 

Je reçois la sortie suivante après l'exécution du code.

rotation mat: 
1.000 0.000 0.000 
0.000 1.000 0.000 
0.000 0.000 1.000 

translation vec: 
[0; 0; 0] 

Répondre

3

La matrice de votre caméra est incorrecte. Votre code devrait lire:

camera_mat.at<double>(0, 0) = 600; 
camera_mat.at<double>(1, 1) = 600; 
camera_mat.at<double>(0, 2) = WIDTH/2; 
camera_mat.at<double>(1, 2) = HEIGHT/2; 
camera_mat.at<double>(3, 3) = 1; 
2

J'ai eu le même problème avant, et il est pas la mauvaise frappe de la matrice de la caméra.
Modifier la déclaration de

Mat camera_mat(3, 3, CV_64FC1); 
Mat distCoeffs(4, 1, CV_64FC1); 

à CV_32FC1 et ne donnent pas la taille initiale de Mat tvec et Mat d.