pnp.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. //
  2. // Created by zx on 22-11-2.
  3. //
  4. #include "pnp.h"
  5. #include <chrono>
  6. cv::Point2d pixel2cam ( const cv::Point2d& p, const cv::Mat& K )
  7. {
  8. return cv::Point2d
  9. (
  10. ( p.x - K.at<double> ( 0,2 ) ) / K.at<double> ( 0,0 ),
  11. ( p.y - K.at<double> ( 1,2 ) ) / K.at<double> ( 1,1 )
  12. );
  13. }
  14. P3d2d::P3d2d(cv::Mat K)
  15. {
  16. K_=K.clone();
  17. }
  18. P3d2d::~P3d2d()
  19. {
  20. }
  21. void P3d2d::Calibrate(std::vector<cv::Point3d> pts_3d,std::vector<cv::Point2d> pts_2d)
  22. {
  23. cv::Mat r;
  24. solvePnP ( pts_3d, pts_2d, K_, cv::Mat(), r, t_, false ); // 调用OpenCV 的 PnP 求解,可选择EPNP,DLS等方法
  25. cv::Rodrigues ( r, R_ ); // r为旋转向量形式,用Rodrigues公式转换为矩阵
  26. }
  27. std::vector<cv::Point3d> P3d2d::execute(std::vector<cv::Point2d> pts_2d)
  28. {
  29. cv::Mat TR=cv::Mat::zeros(3,3,R_.type());
  30. std::vector<cv::Point3d> world_points;
  31. for(int i=0;i<pts_2d.size();i++)
  32. {
  33. cv::Point2d pt = pixel2cam(pts_2d[i], K_);
  34. double a = pt.x;
  35. double b = pt.y;
  36. TR.at<double>(0, 0) = a * R_.at<double>(0, 0) + b * R_.at<double>(0, 1) + R_.at<double>(0, 2);
  37. TR.at<double>(0, 1) = -1;
  38. TR.at<double>(1, 0) = a * R_.at<double>(1, 0) + b * R_.at<double>(1, 1) + R_.at<double>(1, 2);
  39. TR.at<double>(2, 0) = a * R_.at<double>(2, 0) + b * R_.at<double>(2, 1) + R_.at<double>(2, 2);
  40. TR.at<double>(2, 2) = -1;
  41. cv::Mat T = -t_;
  42. cv::Mat dxz = TR.inv() * T;
  43. world_points.push_back(cv::Point3d(dxz.at<double>(1,0),0,dxz.at<double>(2,0)));
  44. }
  45. return world_points;
  46. }