• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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