Wrong position reported by solvePnP

235 views Asked by At

I rendered an image in a simple OpenGL app with a chess board in it at position [0, 0, 6000] and rotation [1.30245, 0.0, 0.0]. I tried detecting corners of the chessboard an even exporting all the positions of chessboard cell corners (they are the same as detected by findChessboardCorners) using OpenCV, but the result returned by solvePnP is tvec: [-1010, -464.251, 11475.2] rvec: [-1.08368, -4.33719e-07, -2.28698e-07] which is totally wrong especially Z coordinate, which is more than 10 times larger than the real one. enter image description here The screen coordinates of the corners (from top left) are:

[630.613, 452.667;
 740.409, 452.667;
 850.204, 452.667;
 960, 452.667;
 1069.8, 452.667;
 1179.59, 452.667;
 1289.39, 452.667;
 618.819, 479.693;
 732.546, 479.693;
 846.273, 479.693;
 960, 479.693;
 1073.73, 479.693;
 1187.45, 479.693;
 1301.18, 479.693;
 606.148, 508.727;
 724.099, 508.727;
 842.049, 508.727;
 960, 508.727;
 1077.95, 508.727;
 1195.9, 508.727;
 1313.85, 508.727;
 592.501, 540;
 715.001, 540;
 837.5, 540;
 960, 540;
 1082.5, 540;
 1205, 540;
 1327.5, 540;
 577.759, 573.782;
 705.172, 573.782;
 832.586, 573.782;
 960, 573.782;
 1087.41, 573.782;
 1214.83, 573.782;
 1342.24, 573.782;
 561.784, 610.388;
 694.523, 610.388;
 827.261, 610.388;
 960, 610.388;
 1092.74, 610.388;
 1225.48, 610.388;
 1358.22, 610.388;
 544.416, 650.187;
 682.944, 650.187;
 821.472, 650.187;
 960, 650.187;
 1098.53, 650.187;
 1237.06, 650.187;
 1375.58, 650.187]

The image of the chessboard: enter image description here

The corner points of the chessboard:

[290, 290, 0;
 530, 290, 0;
 770, 290, 0;
 1010, 290, 0;
 1250, 290, 0;
 1490, 290, 0;
 1730, 290, 0;
 290, 530, 0;
 530, 530, 0;
 770, 530, 0;
 1010, 530, 0;
 1250, 530, 0;
 1490, 530, 0;
 1730, 530, 0;
 290, 770, 0;
 530, 770, 0;
 770, 770, 0;
 1010, 770, 0;
 1250, 770, 0;
 1490, 770, 0;
 1730, 770, 0;
 290, 1010, 0;
 530, 1010, 0;
 770, 1010, 0;
 1010, 1010, 0;
 1250, 1010, 0;
 1490, 1010, 0;
 1730, 1010, 0;
 290, 1250, 0;
 530, 1250, 0;
 770, 1250, 0;
 1010, 1250, 0;
 1250, 1250, 0;
 1490, 1250, 0;
 1730, 1250, 0;
 290, 1490, 0;
 530, 1490, 0;
 770, 1490, 0;
 1010, 1490, 0;
 1250, 1490, 0;
 1490, 1490, 0;
 1730, 1490, 0;
 290, 1730, 0;
 530, 1730, 0;
 770, 1730, 0;
 1010, 1730, 0;
 1250, 1730, 0;
 1490, 1730, 0;
 1730, 1730, 0]

The FOV angle of the camera is 20 degrees (with no distortion). I calculate the camera matrix and use solvePnP as follows:

std::vector<cv::Point2f> corners{...}; // coordinates of the corners in the screenshot
std::vector<cv::Point3f> cornerPoints{...}; // coordinates of the corners in the image of the chessboard

const double w = 1920.0;
const double h = 1080.0;
const auto focalLengthX = (w / 2.0) / std::tan(fieldOfView / 2.0);
const auto focalLengthY = (h / 2.0) / std::tan(fieldOfView / 2.0);
const cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) <<
                              focalLengthX, 0, w/2,
                              0, focalLengthY, h/2,
                              0, 0,   1);
cv::Vec3d rvec;
cv::Vec3d tvec;
const cv::Mat distortion = cv::Mat::zeros(5, 1, CV_32FC1);
const bool ret = cv::solvePnP(cornerPoints, corners, cameraMatrix, distortion,
                              rvec, tvec, false, cv::SOLVEPNP_ITERATIVE);

I tried all the algorithms and they all return a similar result. Am I doing something wrong?

0

There are 0 answers