#include "perf_precomp.hpp" #ifdef HAVE_TBB #include "tbb/task_scheduler_init.h" #endif using namespace std; using namespace cv; using namespace perf; using std::tr1::make_tuple; using std::tr1::get; CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP) typedef std::tr1::tuple PointsNum_Algo_t; typedef perf::TestBaseWithParam PointsNum_Algo; typedef perf::TestBaseWithParam PointsNum; PERF_TEST_P(PointsNum_Algo, solvePnP, testing::Combine( testing::Values(4, 3*9, 7*13), //TODO: find why results on 4 points are too unstable testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_UPNP) ) ) { int pointsNum = get<0>(GetParam()); pnpAlgo algo = get<1>(GetParam()); vector points2d(pointsNum); vector points3d(pointsNum); Mat rvec = Mat::zeros(3, 1, CV_32FC1); Mat tvec = Mat::zeros(3, 1, CV_32FC1); Mat distortion = Mat::zeros(5, 1, CV_32FC1); Mat intrinsics = Mat::eye(3, 3, CV_32FC1); intrinsics.at (0, 0) = 400.0; intrinsics.at (1, 1) = 400.0; intrinsics.at (0, 2) = 640 / 2; intrinsics.at (1, 2) = 480 / 2; warmup(points3d, WARMUP_RNG); warmup(rvec, WARMUP_RNG); warmup(tvec, WARMUP_RNG); projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d); //add noise Mat noise(1, (int)points2d.size(), CV_32FC2); randu(noise, 0, 0.01); add(points2d, noise, points2d); declare.in(points3d, points2d); declare.time(100); TEST_CYCLE_N(1000) { solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo); } SANITY_CHECK(rvec, 1e-6); SANITY_CHECK(tvec, 1e-6); } PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints, testing::Combine( testing::Values(4), //TODO: find why results on 4 points are too unstable testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_DLS) ) ) { int pointsNum = get<0>(GetParam()); pnpAlgo algo = get<1>(GetParam()); vector points2d(pointsNum); vector points3d(pointsNum); Mat rvec = Mat::zeros(3, 1, CV_32FC1); Mat tvec = Mat::zeros(3, 1, CV_32FC1); Mat distortion = Mat::zeros(5, 1, CV_32FC1); Mat intrinsics = Mat::eye(3, 3, CV_32FC1); intrinsics.at (0, 0) = 400.0; intrinsics.at (1, 1) = 400.0; intrinsics.at (0, 2) = 640 / 2; intrinsics.at (1, 2) = 480 / 2; warmup(points3d, WARMUP_RNG); warmup(rvec, WARMUP_RNG); warmup(tvec, WARMUP_RNG); projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d); //add noise Mat noise(1, (int)points2d.size(), CV_32FC2); randu(noise, 0, 0.01); add(points2d, noise, points2d); declare.in(points3d, points2d); declare.time(100); TEST_CYCLE_N(1000) { solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo); } SANITY_CHECK(rvec, 1e-4); SANITY_CHECK(tvec, 1e-2); } PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13)) { int count = GetParam(); Mat object(1, count, CV_32FC3); randu(object, -100, 100); Mat camera_mat(3, 3, CV_32FC1); randu(camera_mat, 0.5, 1); camera_mat.at(0, 1) = 0.f; camera_mat.at(1, 0) = 0.f; camera_mat.at(2, 0) = 0.f; camera_mat.at(2, 1) = 0.f; Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0)); vector image_vec; Mat rvec_gold(1, 3, CV_32FC1); randu(rvec_gold, 0, 1); Mat tvec_gold(1, 3, CV_32FC1); randu(tvec_gold, 0, 1); projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec); Mat image(1, count, CV_32FC2, &image_vec[0]); Mat rvec; Mat tvec; #ifdef HAVE_TBB // limit concurrency to get deterministic result tbb::task_scheduler_init one_thread(1); #endif TEST_CYCLE() { solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec); } SANITY_CHECK(rvec, 1e-6); SANITY_CHECK(tvec, 1e-6); }