Hello everyone,
I am writing this post since I am encountering an issue with solvePnP and solvePnPRansac which I am having a hard time to debug.
So I have been following this tutorial (Head Pose Estimation using OpenCV and Dlib | LearnOpenCV #) to learn about the implementation of solvePnP in OpenCV. The code works on my side, using the given image points, 3D points, camera matrix and distortion coefficients. It also works when I use my own camera matrix and distortion coefficients. So this works :
// 2D image points
std::vector<cv::Point2d> image_points;
image_points.push_back(cv::Point2d(359, 391)); // Nose tip
image_points.push_back(cv::Point2d(399, 561)); // Chin
image_points.push_back(cv::Point2d(337, 297)); // Left eye left corner
image_points.push_back(cv::Point2d(513, 301)); // Right eye right corner
image_points.push_back(cv::Point2d(345, 465)); // Left Mouth corner
image_points.push_back(cv::Point2d(453, 469)); // Right mouth corner
cv::Mat pts = cv::Mat(image_points.size(), 2, CV_64F, image_points.data());
// 3D model points.
std::vector<cv::Point3d> model_points;
model_points.push_back(cv::Point3d(0.0f, 0.0f, 0.0f)); // Nose tip
model_points.push_back(cv::Point3d(0.0f, -330.0f, -65.0f)); // Chin
model_points.push_back(cv::Point3d(-225.0f, 170.0f, -135.0f)); // Left eye left corner
model_points.push_back(cv::Point3d(225.0f, 170.0f, -135.0f)); // Right eye right corner
model_points.push_back(cv::Point3d(-150.0f, -150.0f, -125.0f)); // Left Mouth corner
model_points.push_back(cv::Point3d(150.0f, -150.0f, -125.0f)); // Right mouth corner
cv::Mat mpts = cv::Mat(model_points.size(), 3, CV_64F, model_points.data());
std::cout << "Pts\n" << pts << "\n";
std::cout << "3dPts\n" << mpts << "\n";
std::cout << "Camera Matrix:\n" << cam_mat << "\n" ;
std::cout << "Distortion:\n" << dist_coeff << "\n" ;
// Output rotation and translation
cv::Mat rvec(3, 1, CV_64FC1, cv::Scalar::all(0));
cv::Mat tvec(3, 1, CV_64FC1, cv::Scalar::all(0));
// Solvepnp
//cv::solvePnPRansac(mpts, pts, cam_mat, dist_coeff, rvec, tvec);
cv::solvePnP(mpts, pts, cam_mat, dist_coeff, rvec, tvec);
// reprojecting
std::vector<cv::Point2d> res;
cv::projectPoints(model_points, rvec, tvec, cam_mat, dist_coeff, res);
for(int i=0; i < res.size(); i++)
cv::circle(frame, res[i], 3, cv::Scalar(0, 255, 0), -1);
But here is the catch : when I use my own image points or 3D points the program crashes at the first call of SolvePnP with this data :
std::vector<cv::Point3d> model_points;
model_points.push_back(cv::Point3d(1.7f, 0.0f, 0.0f));
model_points.push_back(cv::Point3d(-1.7f, 0.0f, 0.0f));
model_points.push_back(cv::Point3d(0.0f, 1.7f, 0.0f));
model_points.push_back(cv::Point3d(0.0f, -1.7f, 0.0f));
model_points.push_back(cv::Point3d(2.2f, 0.0f, 3.3f));
model_points.push_back(cv::Point3d(-2.2f, 0.0f, 3.3f));
model_points.push_back(cv::Point3d(0.0f, 2.2f, 3.3f));
model_points.push_back(cv::Point3d(0.0f, -2.2f, 3.3f));
model_points.push_back(cv::Point3d(2.6f, 0.0f, 6.5f));
model_points.push_back(cv::Point3d(-2.6f, 0.0f, 6.5f));
model_points.push_back(cv::Point3d(0.0f, 2.6f, 6.5f));
model_points.push_back(cv::Point3d(2.0f, 0.4f, 9.7f));
model_points.push_back(cv::Point3d(2.0f, 0.4f, 9.7f));
cv::Mat mpts = cv::Mat(model_points.size(), 3, CV_64F, model_points.data());
terminate called without an active exception
Aborted (core dumped)
When replacing both image points and 3D points it also crashes, and when replacing only image points it crashes too. I verified my data it does not contain any NaN or near infinity values.
Here is what I get when replacing both image points and 3D points by my data in the console with the prints :
Pts
[6, 696;
17, 601;
82, 671;
255, 711]
3dPts
[1.700000047683716, 0, 0;
-1.700000047683716, 0, 0;
0, 1.700000047683716, 0;
0, -1.700000047683716, 0;
2.200000047683716, 0, 3.299999952316284;
-2.200000047683716, 0, 3.299999952316284;
0, 2.200000047683716, 3.299999952316284;
0, -2.200000047683716, 3.299999952316284;
2.599999904632568, 0, 6.5;
-2.599999904632568, 0, 6.5;
0, 2.599999904632568, 6.5;
2, 0.4000000059604645, 9.699999809265137;
2, 0.4000000059604645, 9.699999809265137]
Camera Matrix:
[1583.8995, 0, 990.13501;
0, 1585.4629, 620.50098;
0, 0, 1]
Distortion:
[-0.37840971, 0.18232454, -0.0064165886, 0.001675527, -0.017335379]
terminate called without an active exception
Aborted (core dumped)
You might notice that I get my points into a Mat since vectors can apparently cause issues for SolvePnPRansac : opencv - SolvePnP works unstable and crashes - Stack Overflow
SolvePnPRansac also crashes. I already recompiled OpenCV to an earlier version than before (now 3.4.14), this did not fix the error.
I know silent crashes like this are not supposed to happen and this is likely to be a data type issue, but I cannot find it.
Thanks for your help !