Path: blob/master/modules/calib3d/test/test_undistort_points.cpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3#include "test_precomp.hpp"45namespace opencv_test { namespace {67class CV_UndistortTest : public cvtest::BaseTest8{9public:10CV_UndistortTest();11~CV_UndistortTest();12protected:13void run(int);14private:15void generate3DPointCloud(vector<Point3f>& points, Point3f pmin = Point3f(-1,16-1, 5), Point3f pmax = Point3f(1, 1, 10));17void generateCameraMatrix(Mat& cameraMatrix);18void generateDistCoeffs(Mat& distCoeffs, int count);1920double thresh;21RNG rng;22};2324CV_UndistortTest::CV_UndistortTest()25{26thresh = 1.0e-2;27}28CV_UndistortTest::~CV_UndistortTest() {}2930void CV_UndistortTest::generate3DPointCloud(vector<Point3f>& points, Point3f pmin, Point3f pmax)31{32RNG rng_Point = cv::theRNG(); // fix the seed to use "fixed" input 3D points33for (size_t i = 0; i < points.size(); i++)34{35float _x = rng_Point.uniform(pmin.x, pmax.x);36float _y = rng_Point.uniform(pmin.y, pmax.y);37float _z = rng_Point.uniform(pmin.z, pmax.z);38points[i] = Point3f(_x, _y, _z);39}40}41void CV_UndistortTest::generateCameraMatrix(Mat& cameraMatrix)42{43const double fcMinVal = 1e-3;44const double fcMaxVal = 100;45cameraMatrix.create(3, 3, CV_64FC1);46cameraMatrix.setTo(Scalar(0));47cameraMatrix.at<double>(0,0) = rng.uniform(fcMinVal, fcMaxVal);48cameraMatrix.at<double>(1,1) = rng.uniform(fcMinVal, fcMaxVal);49cameraMatrix.at<double>(0,2) = rng.uniform(fcMinVal, fcMaxVal);50cameraMatrix.at<double>(1,2) = rng.uniform(fcMinVal, fcMaxVal);51cameraMatrix.at<double>(2,2) = 1;52}53void CV_UndistortTest::generateDistCoeffs(Mat& distCoeffs, int count)54{55distCoeffs = Mat::zeros(count, 1, CV_64FC1);56for (int i = 0; i < count; i++)57distCoeffs.at<double>(i,0) = rng.uniform(0.0, 1.0e-3);58}5960void CV_UndistortTest::run(int /* start_from */)61{62Mat intrinsics, distCoeffs;63generateCameraMatrix(intrinsics);64vector<Point3f> points(500);65generate3DPointCloud(points);66vector<Point2f> projectedPoints;67projectedPoints.resize(points.size());6869int modelMembersCount[] = {4,5,8};70for (int idx = 0; idx < 3; idx++)71{72generateDistCoeffs(distCoeffs, modelMembersCount[idx]);73projectPoints(Mat(points), Mat::zeros(3,1,CV_64FC1), Mat::zeros(3,1,CV_64FC1), intrinsics, distCoeffs, projectedPoints);7475vector<Point2f> realUndistortedPoints;76projectPoints(Mat(points), Mat::zeros(3,1,CV_64FC1), Mat::zeros(3,1,CV_64FC1), intrinsics, Mat::zeros(4,1,CV_64FC1), realUndistortedPoints);7778Mat undistortedPoints;79undistortPoints(Mat(projectedPoints), undistortedPoints, intrinsics, distCoeffs);8081Mat p;82perspectiveTransform(undistortedPoints, p, intrinsics);83undistortedPoints = p;84double diff = cvtest::norm(Mat(realUndistortedPoints), undistortedPoints, NORM_L2);85if (diff > thresh)86{87ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);88return;89}90ts->set_failed_test_info(cvtest::TS::OK);91}92}9394TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }9596TEST(Calib3d_Undistort, stop_criteria)97{98Mat cameraMatrix = (Mat_<double>(3,3,CV_64F) << 857.48296979, 0, 968.06224829,990, 876.71824265, 556.37145899,1000, 0, 1);101Mat distCoeffs = (Mat_<double>(5,1,CV_64F) <<102-2.57614020e-01, 8.77086999e-02, -2.56970803e-04, -5.93390389e-04, -1.52194091e-02);103RNG rng(2);104Point2d pt_distorted(rng.uniform(0.0, 1920.0), rng.uniform(0.0, 1080.0));105std::vector<Point2d> pt_distorted_vec;106pt_distorted_vec.push_back(pt_distorted);107const double maxError = 1e-6;108TermCriteria criteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 100, maxError);109std::vector<Point2d> pt_undist_vec;110undistortPoints(pt_distorted_vec, pt_undist_vec, cameraMatrix, distCoeffs, noArray(), noArray(), criteria);111112std::vector<Point2d> pt_redistorted_vec;113std::vector<Point3d> pt_undist_vec_homogeneous;114pt_undist_vec_homogeneous.push_back( Point3d(pt_undist_vec[0].x, pt_undist_vec[0].y, 1.0) );115projectPoints(pt_undist_vec_homogeneous, Mat::zeros(3,1,CV_64F), Mat::zeros(3,1,CV_64F), cameraMatrix, distCoeffs, pt_redistorted_vec);116const double obtainedError = sqrt( pow(pt_distorted.x - pt_redistorted_vec[0].x, 2) + pow(pt_distorted.y - pt_redistorted_vec[0].y, 2) );117118ASSERT_LE(obtainedError, maxError);119}120121}} // namespace122123124