perf_pnp.cpp 3.77 KB
Newer Older
1
#include "perf_precomp.hpp"
2
#include "opencv2/core/internal.hpp"
3 4 5 6

using namespace std;
using namespace cv;
using namespace perf;
7 8
using std::tr1::make_tuple;
using std::tr1::get;
9

10
CV_ENUM(pnpAlgo, CV_ITERATIVE, CV_EPNP /*, CV_P3P*/)
11

12 13
typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;
14

Daniil Osokin's avatar
Daniil Osokin committed
15 16
typedef perf::TestBaseWithParam<int> PointsNum;

17 18
PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
19
                testing::Values(/*4,*/ 3*9, 7*13), //TODO: find why results on 4 points are too unstable
20 21 22
                testing::Values((int)CV_ITERATIVE, (int)CV_EPNP)
                )
            )
23
{
24 25
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> 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<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (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
46
    Mat noise(1, (int)points2d.size(), CV_32FC2);
47 48 49 50 51
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);

52 53 54 55
    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }
56 57

    SANITY_CHECK(rvec, 1e-6);
58
    SANITY_CHECK(tvec, 1e-3);
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
}

PERF_TEST(PointsNum_Algo, solveP3P)
{
    int pointsNum = 4;

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> 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<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (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
84
    Mat noise(1, (int)points2d.size(), CV_32FC2);
85 86 87 88
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
Anna Kogan's avatar
Anna Kogan committed
89
    declare.time(100);
90

91 92 93 94
    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, CV_P3P);
    }
95

96 97
    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
98
}
Daniil Osokin's avatar
Daniil Osokin committed
99

100
PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13))
Daniil Osokin's avatar
Daniil Osokin committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
{
    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<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> 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;

128
#ifdef HAVE_TBB
Ilya Lavrenov's avatar
Ilya Lavrenov committed
129
    // limit concurrency to get deterministic result
130 131
    cv::Ptr<tbb::task_scheduler_init> one_thread = new tbb::task_scheduler_init(1);
#endif
Daniil Osokin's avatar
Daniil Osokin committed
132 133 134 135 136

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }
137 138 139

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
Daniil Osokin's avatar
Daniil Osokin committed
140
}