Home | History | Annotate | Download | only in test
      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 
     24 CV_UndistortTest::CV_UndistortTest()
     25 {
     26     thresh = 1.0e-2;
     27 }
     28 CV_UndistortTest::~CV_UndistortTest() {}
     29 
     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 }
     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 }
     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 
     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 
     97 TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
     98