1

I'm trying to compare precision and time consuming between every SolvePnP possibility : CV_ITERATIVE, CV_EPNP, and CV_P3P

I also compared my result with Matlab EPNP.

And it's look like EPNP and P3P failed :

std::vector<cv::Point2f> imgPoints;
imgPoints.push_back(cv::Point2f(400,188));
imgPoints.push_back(cv::Point2f(400,300));
imgPoints.push_back(cv::Point2f(512,300));
imgPoints.push_back(cv::Point2f(512,188));

double size = 80.0;
std::vector<cv::Point3f> objPoints;
objPoints.push_back(cv::Point3f(0,0,0));
objPoints.push_back(cv::Point3f(0,size,0));
objPoints.push_back(cv::Point3f(size,size,0));
objPoints.push_back(cv::Point3f(size,0,0));

cv::Mat rvec0 = cv::Mat::zeros(3, 1, CV_64FC1);
cv::Mat tvec0 = cv::Mat::zeros(3, 1, CV_64FC1);

cv::Mat rvec1 = cv::Mat::zeros(3, 1, CV_64FC1);
cv::Mat tvec1 = cv::Mat::zeros(3, 1, CV_64FC1);

cv::Mat rvec2 = cv::Mat::zeros(3, 1, CV_64FC1);
cv::Mat tvec2 = cv::Mat::zeros(3, 1, CV_64FC1);

cv::Mat cam, coeff;
cam = (cv::Mat_<double>(3,3) << 700,0,300,0,700,400,0,0,1);
cv::solvePnP(objPoints,imgPoints,cam,coeff,rvec0,tvec0,CV_ITERATIVE);
cv::solvePnP(objPoints,imgPoints,cam,coeff,rvec1,tvec1,CV_P3P);
cv::solvePnP(objPoints,imgPoints,cam,coeff,rvec2,tvec2,CV_EPNP);

cv::Mat rmat0,rmat1,rmat2;
cv::Rodrigues(rvec0,rmat0);
cv::Rodrigues(rvec1,rmat1);
cv::Rodrigues(rvec2,rmat2);

std::cout << "ITERATIVE : Rotation matrix : " << std::endl << rmat0 << std::endl;
std::cout << "ITERATIVE : Tranlation vector : " << std::endl << tvec0 << std::endl << std::endl;

std::cout << "P3P : Rotation matrix : " << std::endl << rmat1 << std::endl;
std::cout << "P3P : Tranlation vector : " << std::endl << tvec1 << std::endl << std::endl;

std::cout << "EPNP : Rotation matrix : " << std::endl << rmat2 << std::endl;
std::cout << "EPNP : Tranlation vector : " << std::endl << tvec2  << std::endl << std::endl;

Give me :

ITERATIVE : Rotation matrix : [1, -2.196885546074445e-016, 9.692430825310778e-016; 2.196885546074445e-016, 1, 1.012059558506939e-015; -9.692430825310778e-016, -1.012059558506939e-015, 1]

ITERATIVE : Tranlation vector : [71.42857142857143; -151.4285714285714; 500]

P3P : Rotation matrix : [1, 0, 0; 0, 1, 0; 0, 0, 1]

P3P : Tranlation vector : [-3.97771428571427e-015; -4.022285714285698e-015; 9.989999999999962e-017]

EPNP : Rotation matrix : [1, 0, 0; 0, 1, 0; 0, 0, 1]

EPNP : Tranlation vector : [-3.97771428571427e-015; -4.022285714285698e-015; 9.989999999999962e-017]

Any suggestion ?

Alexandre Kornmann

user3766777
  • 11
  • 1
  • 2
  • Have you tried other data points & more (4>) data? – Nallath Jun 23 '14 at 09:13
  • I tried other data points, it works sometime successfully, sometime not. But for my application, I need : it works always successfully ... I tried also with 16 points, it works sometime successfully, sometime not... – user3766777 Jun 23 '14 at 09:49

2 Answers2

1

I have hints for you, some things sounds strange for me :

  1. You give (300,400) for center point in the cam matrix, so your image is 600*800 (vertical) ?
  2. For the projection position of your 2D points, be sure you put them in the OpenCV way : the (0,0) point in an image is the top left corner.
  3. Your points are coplanar (plane z=0) and maybe solvePnP is sensitive to this.
caymard
  • 158
  • 2
  • 10
  • 1: Right, this is a mistake but using 400,300 correct only iterative error I had when I check my result with Matlab. EPNP and P3P are still unstable. 2. OpenCV order = top/ left -> bottom->left -> bottom/right -> top right ? (400,188) -> (400,300) -> (512,300) -> (512,188) => (0,0,0) -> (0,1,0) -> (1,1,0) -> (1,0,0) 3. Yes, I heard about PnP sensitivity for coplanar point. But for AR, my marker are planar... – user3766777 Jun 23 '14 at 11:36
  • 1
    An other hints from OpenCV support was to use point 3D coordinate in range [-1;1] instead of [0;80]. With this CV_ITERATIVE, CV_P3p, CV_EPNP give mes ame results, but it's not really an intuitive way to use coordinates in real space... But it works for next one who's stuck like I was :) – user3766777 Jun 23 '14 at 11:36
0

P3P is'not a good method,it's precision is very poor.EPNP seems like a best choice in precision.But you shouldn't use EPNP only,with Ransac algorithm will be better.