perf_pnp.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "perf_precomp.hpp"
  2. namespace opencv_test
  3. {
  4. using namespace perf;
  5. CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)
  6. typedef tuple<int, pnpAlgo> PointsNum_Algo_t;
  7. typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;
  8. typedef perf::TestBaseWithParam<int> PointsNum;
  9. PERF_TEST_P(PointsNum_Algo, solvePnP,
  10. testing::Combine( //When non planar, DLT needs at least 6 points for SOLVEPNP_ITERATIVE flag
  11. testing::Values(6, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
  12. testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_UPNP, (int)SOLVEPNP_DLS)
  13. )
  14. )
  15. {
  16. int pointsNum = get<0>(GetParam());
  17. pnpAlgo algo = get<1>(GetParam());
  18. vector<Point2f> points2d(pointsNum);
  19. vector<Point3f> points3d(pointsNum);
  20. Mat rvec = Mat::zeros(3, 1, CV_32FC1);
  21. Mat tvec = Mat::zeros(3, 1, CV_32FC1);
  22. Mat distortion = Mat::zeros(5, 1, CV_32FC1);
  23. Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
  24. intrinsics.at<float> (0, 0) = 400.0;
  25. intrinsics.at<float> (1, 1) = 400.0;
  26. intrinsics.at<float> (0, 2) = 640 / 2;
  27. intrinsics.at<float> (1, 2) = 480 / 2;
  28. warmup(points3d, WARMUP_RNG);
  29. warmup(rvec, WARMUP_RNG);
  30. warmup(tvec, WARMUP_RNG);
  31. projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);
  32. //add noise
  33. Mat noise(1, (int)points2d.size(), CV_32FC2);
  34. randu(noise, 0, 0.01);
  35. cv::add(points2d, noise, points2d);
  36. declare.in(points3d, points2d);
  37. declare.time(100);
  38. TEST_CYCLE_N(1000)
  39. {
  40. cv::solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
  41. }
  42. SANITY_CHECK(rvec, 1e-4);
  43. SANITY_CHECK(tvec, 1e-4);
  44. }
  45. PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
  46. testing::Combine(
  47. testing::Values(5),
  48. testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
  49. )
  50. )
  51. {
  52. int pointsNum = get<0>(GetParam());
  53. pnpAlgo algo = get<1>(GetParam());
  54. if( algo == SOLVEPNP_P3P )
  55. pointsNum = 4;
  56. vector<Point2f> points2d(pointsNum);
  57. vector<Point3f> points3d(pointsNum);
  58. Mat rvec = Mat::zeros(3, 1, CV_32FC1);
  59. Mat tvec = Mat::zeros(3, 1, CV_32FC1);
  60. Mat distortion = Mat::zeros(5, 1, CV_32FC1);
  61. Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
  62. intrinsics.at<float> (0, 0) = 400.0f;
  63. intrinsics.at<float> (1, 1) = 400.0f;
  64. intrinsics.at<float> (0, 2) = 640 / 2;
  65. intrinsics.at<float> (1, 2) = 480 / 2;
  66. warmup(points3d, WARMUP_RNG);
  67. warmup(rvec, WARMUP_RNG);
  68. warmup(tvec, WARMUP_RNG);
  69. // normalize Rodrigues vector
  70. Mat rvec_tmp = Mat::eye(3, 3, CV_32F);
  71. cv::Rodrigues(rvec, rvec_tmp);
  72. cv::Rodrigues(rvec_tmp, rvec);
  73. cv::projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);
  74. //add noise
  75. Mat noise(1, (int)points2d.size(), CV_32FC2);
  76. randu(noise, -0.001, 0.001);
  77. cv::add(points2d, noise, points2d);
  78. declare.in(points3d, points2d);
  79. declare.time(100);
  80. TEST_CYCLE_N(1000)
  81. {
  82. cv::solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
  83. }
  84. SANITY_CHECK(rvec, 1e-1);
  85. SANITY_CHECK(tvec, 1e-2);
  86. }
  87. PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(5, 3*9, 7*13))
  88. {
  89. int count = GetParam();
  90. Mat object(1, count, CV_32FC3);
  91. randu(object, -100, 100);
  92. Mat camera_mat(3, 3, CV_32FC1);
  93. randu(camera_mat, 0.5, 1);
  94. camera_mat.at<float>(0, 1) = 0.f;
  95. camera_mat.at<float>(1, 0) = 0.f;
  96. camera_mat.at<float>(2, 0) = 0.f;
  97. camera_mat.at<float>(2, 1) = 0.f;
  98. Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));
  99. vector<cv::Point2f> image_vec;
  100. Mat rvec_gold(1, 3, CV_32FC1);
  101. randu(rvec_gold, 0, 1);
  102. Mat tvec_gold(1, 3, CV_32FC1);
  103. randu(tvec_gold, 0, 1);
  104. projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);
  105. Mat image(1, count, CV_32FC2, &image_vec[0]);
  106. Mat rvec;
  107. Mat tvec;
  108. TEST_CYCLE()
  109. {
  110. cv::solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
  111. }
  112. SANITY_CHECK(rvec, 1e-6);
  113. SANITY_CHECK(tvec, 1e-6);
  114. }
  115. } // namespace