1 #include "test_precomp.hpp"
2 #include <string>
3
4 using namespace cv;
5 using namespace std;
6
7 class CV_UndistortTest : public cvtest::BaseTest
8 {
9 public:
10 CV_UndistortTest();
11 ~CV_UndistortTest();
12 protected:
13 void run(int);
14 private:
15 void generate3DPointCloud(vector<Point3f>& points, Point3f pmin = Point3f(-1,
16 -1, 5), Point3f pmax = Point3f(1, 1, 10));
17 void generateCameraMatrix(Mat& cameraMatrix);
18 void generateDistCoeffs(Mat& distCoeffs, int count);
19
20 double thresh;
21 RNG rng;
22 };
23
CV_UndistortTest()24 CV_UndistortTest::CV_UndistortTest()
25 {
26 thresh = 1.0e-2;
27 }
~CV_UndistortTest()28 CV_UndistortTest::~CV_UndistortTest() {}
29
generate3DPointCloud(vector<Point3f> & points,Point3f pmin,Point3f pmax)30 void CV_UndistortTest::generate3DPointCloud(vector<Point3f>& points, Point3f pmin, Point3f pmax)
31 {
32 const Point3f delta = pmax - pmin;
33 for (size_t i = 0; i < points.size(); i++)
34 {
35 Point3f p(float(rand()) / RAND_MAX, float(rand()) / RAND_MAX,
36 float(rand()) / RAND_MAX);
37 p.x *= delta.x;
38 p.y *= delta.y;
39 p.z *= delta.z;
40 p = p + pmin;
41 points[i] = p;
42 }
43 }
generateCameraMatrix(Mat & cameraMatrix)44 void CV_UndistortTest::generateCameraMatrix(Mat& cameraMatrix)
45 {
46 const double fcMinVal = 1e-3;
47 const double fcMaxVal = 100;
48 cameraMatrix.create(3, 3, CV_64FC1);
49 cameraMatrix.setTo(Scalar(0));
50 cameraMatrix.at<double>(0,0) = rng.uniform(fcMinVal, fcMaxVal);
51 cameraMatrix.at<double>(1,1) = rng.uniform(fcMinVal, fcMaxVal);
52 cameraMatrix.at<double>(0,2) = rng.uniform(fcMinVal, fcMaxVal);
53 cameraMatrix.at<double>(1,2) = rng.uniform(fcMinVal, fcMaxVal);
54 cameraMatrix.at<double>(2,2) = 1;
55 }
generateDistCoeffs(Mat & distCoeffs,int count)56 void CV_UndistortTest::generateDistCoeffs(Mat& distCoeffs, int count)
57 {
58 distCoeffs = Mat::zeros(count, 1, CV_64FC1);
59 for (int i = 0; i < count; i++)
60 distCoeffs.at<double>(i,0) = rng.uniform(0.0, 1.0e-3);
61 }
62
run(int)63 void CV_UndistortTest::run(int /* start_from */)
64 {
65 Mat intrinsics, distCoeffs;
66 generateCameraMatrix(intrinsics);
67 vector<Point3f> points(500);
68 generate3DPointCloud(points);
69 vector<Point2f> projectedPoints;
70 projectedPoints.resize(points.size());
71
72 int modelMembersCount[] = {4,5,8};
73 for (int idx = 0; idx < 3; idx++)
74 {
75 generateDistCoeffs(distCoeffs, modelMembersCount[idx]);
76 projectPoints(Mat(points), Mat::zeros(3,1,CV_64FC1), Mat::zeros(3,1,CV_64FC1), intrinsics, distCoeffs, projectedPoints);
77
78 vector<Point2f> realUndistortedPoints;
79 projectPoints(Mat(points), Mat::zeros(3,1,CV_64FC1), Mat::zeros(3,1,CV_64FC1), intrinsics, Mat::zeros(4,1,CV_64FC1), realUndistortedPoints);
80
81 Mat undistortedPoints;
82 undistortPoints(Mat(projectedPoints), undistortedPoints, intrinsics, distCoeffs);
83
84 Mat p;
85 perspectiveTransform(undistortedPoints, p, intrinsics);
86 undistortedPoints = p;
87 double diff = cvtest::norm(Mat(realUndistortedPoints), undistortedPoints, NORM_L2);
88 if (diff > thresh)
89 {
90 ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
91 return;
92 }
93 ts->set_failed_test_info(cvtest::TS::OK);
94 }
95 }
96
TEST(Calib3d_Undistort,accuracy)97 TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
98