Path: blob/master/modules/calib3d/test/test_undistort.cpp
16337 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.13// Copyright (C) 2009, Willow Garage Inc., all rights reserved.14// Third party copyrights are property of their respective owners.15//16// Redistribution and use in source and binary forms, with or without modification,17// are permitted provided that the following conditions are met:18//19// * Redistribution's of source code must retain the above copyright notice,20// this list of conditions and the following disclaimer.21//22// * Redistribution's in binary form must reproduce the above copyright notice,23// this list of conditions and the following disclaimer in the documentation24// and/or other materials provided with the distribution.25//26// * The name of the copyright holders may not be used to endorse or promote products27// derived from this software without specific prior written permission.28//29// This software is provided by the copyright holders and contributors "as is" and30// any express or implied warranties, including, but not limited to, the implied31// warranties of merchantability and fitness for a particular purpose are disclaimed.32// In no event shall the Intel Corporation or contributors be liable for any direct,33// indirect, incidental, special, exemplary, or consequential damages34// (including, but not limited to, procurement of substitute goods or services;35// loss of use, data, or profits; or business interruption) however caused36// and on any theory of liability, whether in contract, strict liability,37// or tort (including negligence or otherwise) arising in any way out of38// the use of this software, even if advised of the possibility of such damage.39//40//M*/4142#include "test_precomp.hpp"43#include "opencv2/imgproc/imgproc_c.h"44#include "opencv2/calib3d/calib3d_c.h"4546namespace opencv_test { namespace {4748class CV_DefaultNewCameraMatrixTest : public cvtest::ArrayTest49{50public:51CV_DefaultNewCameraMatrixTest();52protected:53int prepare_test_case (int test_case_idx);54void prepare_to_validation( int test_case_idx );55void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );56void run_func();5758private:59cv::Size img_size;60cv::Mat camera_mat;61cv::Mat new_camera_mat;6263int matrix_type;6465bool center_principal_point;6667static const int MAX_X = 2048;68static const int MAX_Y = 2048;69//static const int MAX_VAL = 10000;70};7172CV_DefaultNewCameraMatrixTest::CV_DefaultNewCameraMatrixTest()73{74test_array[INPUT].push_back(NULL);75test_array[OUTPUT].push_back(NULL);76test_array[REF_OUTPUT].push_back(NULL);7778matrix_type = 0;79center_principal_point = false;80}8182void CV_DefaultNewCameraMatrixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )83{84cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx,sizes,types);85RNG& rng = ts->get_rng();86matrix_type = types[INPUT][0] = types[OUTPUT][0]= types[REF_OUTPUT][0] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;87sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,3);88}8990int CV_DefaultNewCameraMatrixTest::prepare_test_case(int test_case_idx)91{92int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );9394if (code <= 0)95return code;9697RNG& rng = ts->get_rng();9899img_size.width = cvtest::randInt(rng) % MAX_X + 1;100img_size.height = cvtest::randInt(rng) % MAX_Y + 1;101102center_principal_point = ((cvtest::randInt(rng) % 2)!=0);103104// Generating camera_mat matrix105double sz = MAX(img_size.width, img_size.height);106double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;107double a[9] = {0,0,0,0,0,0,0,0,1};108Mat _a(3,3,CV_64F,a);109a[2] = (img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;110a[5] = (img_size.height - 1)*0.5 + cvtest::randReal(rng)*10 - 5;111a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);112a[4] = aspect_ratio*a[0];113114Mat& _a0 = test_mat[INPUT][0];115cvtest::convert(_a, _a0, _a0.type());116camera_mat = _a0;117118return code;119120}121122void CV_DefaultNewCameraMatrixTest::run_func()123{124new_camera_mat = cv::getDefaultNewCameraMatrix(camera_mat,img_size,center_principal_point);125}126127void CV_DefaultNewCameraMatrixTest::prepare_to_validation( int /*test_case_idx*/ )128{129const Mat& src = test_mat[INPUT][0];130Mat& dst = test_mat[REF_OUTPUT][0];131Mat& test_output = test_mat[OUTPUT][0];132Mat& output = new_camera_mat;133cvtest::convert( output, test_output, test_output.type() );134if (!center_principal_point)135{136cvtest::copy(src, dst);137}138else139{140double a[9] = {0,0,0,0,0,0,0,0,1};141Mat _a(3,3,CV_64F,a);142if (matrix_type == CV_64F)143{144a[0] = src.at<double>(0,0);145a[4] = src.at<double>(1,1);146}147else148{149a[0] = src.at<float>(0,0);150a[4] = src.at<float>(1,1);151}152a[2] = (img_size.width - 1)*0.5;153a[5] = (img_size.height - 1)*0.5;154cvtest::convert( _a, dst, dst.type() );155}156}157158//---------159160class CV_UndistortPointsTest : public cvtest::ArrayTest161{162public:163CV_UndistortPointsTest();164protected:165int prepare_test_case (int test_case_idx);166void prepare_to_validation( int test_case_idx );167void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );168double get_success_error_level( int test_case_idx, int i, int j );169void run_func();170void distortPoints(const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,171const CvMat* _distCoeffs, const CvMat* matR, const CvMat* matP);172173private:174bool useCPlus;175bool useDstMat;176static const int N_POINTS = 10;177static const int MAX_X = 2048;178static const int MAX_Y = 2048;179180bool zero_new_cam;181bool zero_distortion;182bool zero_R;183184cv::Size img_size;185cv::Mat dst_points_mat;186187cv::Mat camera_mat;188cv::Mat R;189cv::Mat P;190cv::Mat distortion_coeffs;191cv::Mat src_points;192std::vector<cv::Point2f> dst_points;193};194195CV_UndistortPointsTest::CV_UndistortPointsTest()196{197test_array[INPUT].push_back(NULL); // points matrix198test_array[INPUT].push_back(NULL); // camera matrix199test_array[INPUT].push_back(NULL); // distortion coeffs200test_array[INPUT].push_back(NULL); // R matrix201test_array[INPUT].push_back(NULL); // P matrix202test_array[OUTPUT].push_back(NULL); // distorted dst points203test_array[TEMP].push_back(NULL); // dst points204test_array[REF_OUTPUT].push_back(NULL);205206useCPlus = useDstMat = false;207zero_new_cam = zero_distortion = zero_R = false;208}209210void CV_UndistortPointsTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )211{212cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx,sizes,types);213RNG& rng = ts->get_rng();214useCPlus = ((cvtest::randInt(rng) % 2)!=0);215//useCPlus = 0;216if (useCPlus)217{218types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = types[TEMP][0]= CV_32FC2;219}220else221{222types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = types[TEMP][0]= cvtest::randInt(rng)%2 ? CV_64FC2 : CV_32FC2;223}224types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;225types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;226types[INPUT][3] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;227types[INPUT][4] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;228229sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sizes[TEMP][0]= cvtest::randInt(rng)%2 ? cvSize(1,N_POINTS) : cvSize(N_POINTS,1);230sizes[INPUT][1] = sizes[INPUT][3] = cvSize(3,3);231sizes[INPUT][4] = cvtest::randInt(rng)%2 ? cvSize(3,3) : cvSize(4,3);232233if (cvtest::randInt(rng)%2)234{235if (cvtest::randInt(rng)%2)236{237sizes[INPUT][2] = cvSize(1,4);238}239else240{241sizes[INPUT][2] = cvSize(1,5);242}243}244else245{246if (cvtest::randInt(rng)%2)247{248sizes[INPUT][2] = cvSize(4,1);249}250else251{252sizes[INPUT][2] = cvSize(5,1);253}254}255}256257int CV_UndistortPointsTest::prepare_test_case(int test_case_idx)258{259RNG& rng = ts->get_rng();260int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );261262if (code <= 0)263return code;264265useDstMat = (cvtest::randInt(rng) % 2) == 0;266267img_size.width = cvtest::randInt(rng) % MAX_X + 1;268img_size.height = cvtest::randInt(rng) % MAX_Y + 1;269int dist_size = test_mat[INPUT][2].cols > test_mat[INPUT][2].rows ? test_mat[INPUT][2].cols : test_mat[INPUT][2].rows;270double cam[9] = {0,0,0,0,0,0,0,0,1};271vector<double> dist(dist_size);272vector<double> proj(test_mat[INPUT][4].cols * test_mat[INPUT][4].rows);273vector<Point2d> points(N_POINTS);274275Mat _camera(3,3,CV_64F,cam);276Mat _distort(test_mat[INPUT][2].rows,test_mat[INPUT][2].cols,CV_64F,&dist[0]);277Mat _proj(test_mat[INPUT][4].size(), CV_64F, &proj[0]);278Mat _points(test_mat[INPUT][0].size(), CV_64FC2, &points[0]);279280_proj = Scalar::all(0);281282//Generating points283for( int i = 0; i < N_POINTS; i++ )284{285points[i].x = cvtest::randReal(rng)*img_size.width;286points[i].y = cvtest::randReal(rng)*img_size.height;287}288289//Generating camera matrix290double sz = MAX(img_size.width,img_size.height);291double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;292cam[2] = (img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;293cam[5] = (img_size.height - 1)*0.5 + cvtest::randReal(rng)*10 - 5;294cam[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);295cam[4] = aspect_ratio*cam[0];296297//Generating distortion coeffs298dist[0] = cvtest::randReal(rng)*0.06 - 0.03;299dist[1] = cvtest::randReal(rng)*0.06 - 0.03;300if( dist[0]*dist[1] > 0 )301dist[1] = -dist[1];302if( cvtest::randInt(rng)%4 != 0 )303{304dist[2] = cvtest::randReal(rng)*0.004 - 0.002;305dist[3] = cvtest::randReal(rng)*0.004 - 0.002;306if (dist_size > 4)307dist[4] = cvtest::randReal(rng)*0.004 - 0.002;308}309else310{311dist[2] = dist[3] = 0;312if (dist_size > 4)313dist[4] = 0;314}315316//Generating P matrix (projection)317if( test_mat[INPUT][4].cols != 4 )318{319proj[8] = 1;320if (cvtest::randInt(rng)%2 == 0) // use identity new camera matrix321{322proj[0] = 1;323proj[4] = 1;324}325else326{327proj[0] = cam[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[0]; //10%328proj[4] = cam[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[4]; //10%329proj[2] = cam[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.width; //15%330proj[5] = cam[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.height; //15%331}332}333else334{335proj[10] = 1;336proj[0] = cam[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[0]; //10%337proj[5] = cam[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[4]; //10%338proj[2] = cam[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.width; //15%339proj[6] = cam[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.height; //15%340341proj[3] = (img_size.height + img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;342proj[7] = (img_size.height + img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;343proj[11] = (img_size.height + img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;344}345346//Generating R matrix347Mat _rot(3,3,CV_64F);348Mat rotation(1,3,CV_64F);349rotation.at<double>(0) = CV_PI*(cvtest::randReal(rng) - (double)0.5); // phi350rotation.at<double>(1) = CV_PI*(cvtest::randReal(rng) - (double)0.5); // ksi351rotation.at<double>(2) = CV_PI*(cvtest::randReal(rng) - (double)0.5); //khi352cvtest::Rodrigues(rotation, _rot);353354//copying data355//src_points = &_points;356_points.convertTo(test_mat[INPUT][0], test_mat[INPUT][0].type());357_camera.convertTo(test_mat[INPUT][1], test_mat[INPUT][1].type());358_distort.convertTo(test_mat[INPUT][2], test_mat[INPUT][2].type());359_rot.convertTo(test_mat[INPUT][3], test_mat[INPUT][3].type());360_proj.convertTo(test_mat[INPUT][4], test_mat[INPUT][4].type());361362zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;363zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;364zero_R = (cvtest::randInt(rng)%2) == 0 ? false : true;365366if (useCPlus)367{368_points.convertTo(src_points, CV_32F);369370camera_mat = test_mat[INPUT][1];371distortion_coeffs = test_mat[INPUT][2];372R = test_mat[INPUT][3];373P = test_mat[INPUT][4];374}375376return code;377}378379void CV_UndistortPointsTest::prepare_to_validation(int /*test_case_idx*/)380{381int dist_size = test_mat[INPUT][2].cols > test_mat[INPUT][2].rows ? test_mat[INPUT][2].cols : test_mat[INPUT][2].rows;382double cam[9] = {0,0,0,0,0,0,0,0,1};383double rot[9] = {1,0,0,0,1,0,0,0,1};384385double* dist = new double[dist_size ];386double* proj = new double[test_mat[INPUT][4].cols * test_mat[INPUT][4].rows];387double* points = new double[N_POINTS*2];388double* r_points = new double[N_POINTS*2];389//Run reference calculations390CvMat ref_points= cvMat(test_mat[INPUT][0].rows,test_mat[INPUT][0].cols,CV_64FC2,r_points);391CvMat _camera = cvMat(3,3,CV_64F,cam);392CvMat _rot = cvMat(3,3,CV_64F,rot);393CvMat _distort = cvMat(test_mat[INPUT][2].rows,test_mat[INPUT][2].cols,CV_64F,dist);394CvMat _proj = cvMat(test_mat[INPUT][4].rows,test_mat[INPUT][4].cols,CV_64F,proj);395CvMat _points= cvMat(test_mat[TEMP][0].rows,test_mat[TEMP][0].cols,CV_64FC2,points);396397Mat __camera = cvarrToMat(&_camera);398Mat __distort = cvarrToMat(&_distort);399Mat __rot = cvarrToMat(&_rot);400Mat __proj = cvarrToMat(&_proj);401Mat __points = cvarrToMat(&_points);402Mat _ref_points = cvarrToMat(&ref_points);403404cvtest::convert(test_mat[INPUT][1], __camera, __camera.type());405cvtest::convert(test_mat[INPUT][2], __distort, __distort.type());406cvtest::convert(test_mat[INPUT][3], __rot, __rot.type());407cvtest::convert(test_mat[INPUT][4], __proj, __proj.type());408409if (useCPlus)410{411if (useDstMat)412{413CvMat temp = cvMat(dst_points_mat);414for (int i=0;i<N_POINTS*2;i++)415{416points[i] = temp.data.fl[i];417}418}419else420{421for (int i=0;i<N_POINTS;i++)422{423points[2*i] = dst_points[i].x;424points[2*i+1] = dst_points[i].y;425}426}427}428else429{430cvtest::convert(test_mat[TEMP][0],__points, __points.type());431}432433CvMat* input2 = zero_distortion ? 0 : &_distort;434CvMat* input3 = zero_R ? 0 : &_rot;435CvMat* input4 = zero_new_cam ? 0 : &_proj;436distortPoints(&_points,&ref_points,&_camera,input2,input3,input4);437438Mat& dst = test_mat[REF_OUTPUT][0];439cvtest::convert(_ref_points, dst, dst.type());440441cvtest::copy(test_mat[INPUT][0], test_mat[OUTPUT][0]);442443delete[] dist;444delete[] proj;445delete[] points;446delete[] r_points;447}448449void CV_UndistortPointsTest::run_func()450{451452if (useCPlus)453{454cv::Mat input2,input3,input4;455input2 = zero_distortion ? cv::Mat() : cv::Mat(test_mat[INPUT][2]);456input3 = zero_R ? cv::Mat() : cv::Mat(test_mat[INPUT][3]);457input4 = zero_new_cam ? cv::Mat() : cv::Mat(test_mat[INPUT][4]);458459if (useDstMat)460{461//cv::undistortPoints(src_points,dst_points_mat,camera_mat,distortion_coeffs,R,P);462cv::undistortPoints(src_points,dst_points_mat,camera_mat,input2,input3,input4);463}464else465{466//cv::undistortPoints(src_points,dst_points,camera_mat,distortion_coeffs,R,P);467cv::undistortPoints(src_points,dst_points,camera_mat,input2,input3,input4);468}469}470else471{472CvMat _input0 = cvMat(test_mat[INPUT][0]), _input1 = cvMat(test_mat[INPUT][1]), _input2, _input3, _input4;473CvMat _output = cvMat(test_mat[TEMP][0]);474if(!zero_distortion)475_input2 = cvMat(test_mat[INPUT][2]);476if(!zero_R)477_input3 = cvMat(test_mat[INPUT][3]);478if(!zero_new_cam)479_input4 = cvMat(test_mat[INPUT][4]);480cvUndistortPoints(&_input0, &_output, &_input1,481zero_distortion ? 0 : &_input2,482zero_R ? 0 : &_input3,483zero_new_cam ? 0 : &_input4);484}485}486487void CV_UndistortPointsTest::distortPoints(const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,488const CvMat* _distCoeffs,489const CvMat* matR, const CvMat* matP)490{491double a[9];492493CvMat* __P;494if ((!matP)||(matP->cols == 3))495__P = cvCreateMat(3,3,CV_64F);496else497__P = cvCreateMat(3,4,CV_64F);498if (matP)499{500cvtest::convert(cvarrToMat(matP), cvarrToMat(__P), -1);501}502else503{504cvZero(__P);505__P->data.db[0] = 1;506__P->data.db[4] = 1;507__P->data.db[8] = 1;508}509CvMat* __R = cvCreateMat(3,3,CV_64F);510if (matR)511{512cvCopy(matR,__R);513}514else515{516cvZero(__R);517__R->data.db[0] = 1;518__R->data.db[4] = 1;519__R->data.db[8] = 1;520}521for (int i=0;i<N_POINTS;i++)522{523int movement = __P->cols > 3 ? 1 : 0;524double x = (_src->data.db[2*i]-__P->data.db[2])/__P->data.db[0];525double y = (_src->data.db[2*i+1]-__P->data.db[5+movement])/__P->data.db[4+movement];526CvMat inverse = cvMat(3,3,CV_64F,a);527cvInvert(__R,&inverse);528double w1 = x*inverse.data.db[6]+y*inverse.data.db[7]+inverse.data.db[8];529double _x = (x*inverse.data.db[0]+y*inverse.data.db[1]+inverse.data.db[2])/w1;530double _y = (x*inverse.data.db[3]+y*inverse.data.db[4]+inverse.data.db[5])/w1;531532//Distortions533534double __x = _x;535double __y = _y;536if (_distCoeffs)537{538double r2 = _x*_x+_y*_y;539540__x = _x*(1+_distCoeffs->data.db[0]*r2+_distCoeffs->data.db[1]*r2*r2)+5412*_distCoeffs->data.db[2]*_x*_y+_distCoeffs->data.db[3]*(r2+2*_x*_x);542__y = _y*(1+_distCoeffs->data.db[0]*r2+_distCoeffs->data.db[1]*r2*r2)+5432*_distCoeffs->data.db[3]*_x*_y+_distCoeffs->data.db[2]*(r2+2*_y*_y);544if ((_distCoeffs->cols > 4) || (_distCoeffs->rows > 4))545{546__x+=_x*_distCoeffs->data.db[4]*r2*r2*r2;547__y+=_y*_distCoeffs->data.db[4]*r2*r2*r2;548}549}550551552_dst->data.db[2*i] = __x*_cameraMatrix->data.db[0]+_cameraMatrix->data.db[2];553_dst->data.db[2*i+1] = __y*_cameraMatrix->data.db[4]+_cameraMatrix->data.db[5];554555}556557cvReleaseMat(&__R);558cvReleaseMat(&__P);559560}561562563double CV_UndistortPointsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )564{565return 5e-2;566}567568//------------------------------------------------------569570class CV_InitUndistortRectifyMapTest : public cvtest::ArrayTest571{572public:573CV_InitUndistortRectifyMapTest();574protected:575int prepare_test_case (int test_case_idx);576void prepare_to_validation( int test_case_idx );577void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );578double get_success_error_level( int test_case_idx, int i, int j );579void run_func();580581private:582bool useCPlus;583static const int N_POINTS = 100;584static const int MAX_X = 2048;585static const int MAX_Y = 2048;586bool zero_new_cam;587bool zero_distortion;588bool zero_R;589590591cv::Size img_size;592593cv::Mat camera_mat;594cv::Mat R;595cv::Mat new_camera_mat;596cv::Mat distortion_coeffs;597cv::Mat mapx;598cv::Mat mapy;599CvMat* _mapx;600CvMat* _mapy;601int mat_type;602};603604CV_InitUndistortRectifyMapTest::CV_InitUndistortRectifyMapTest()605{606test_array[INPUT].push_back(NULL); // test points matrix607test_array[INPUT].push_back(NULL); // camera matrix608test_array[INPUT].push_back(NULL); // distortion coeffs609test_array[INPUT].push_back(NULL); // R matrix610test_array[INPUT].push_back(NULL); // new camera matrix611test_array[OUTPUT].push_back(NULL); // distorted dst points612test_array[REF_OUTPUT].push_back(NULL);613614useCPlus = false;615zero_distortion = zero_new_cam = zero_R = false;616_mapx = _mapy = NULL;617mat_type = 0;618}619620void CV_InitUndistortRectifyMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )621{622cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx,sizes,types);623RNG& rng = ts->get_rng();624useCPlus = ((cvtest::randInt(rng) % 2)!=0);625//useCPlus = 0;626types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC2;627628types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;629types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;630types[INPUT][3] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;631types[INPUT][4] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;632633sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(N_POINTS,1);634sizes[INPUT][1] = sizes[INPUT][3] = cvSize(3,3);635sizes[INPUT][4] = cvSize(3,3);636637if (cvtest::randInt(rng)%2)638{639if (cvtest::randInt(rng)%2)640{641sizes[INPUT][2] = cvSize(1,4);642}643else644{645sizes[INPUT][2] = cvSize(1,5);646}647}648else649{650if (cvtest::randInt(rng)%2)651{652sizes[INPUT][2] = cvSize(4,1);653}654else655{656sizes[INPUT][2] = cvSize(5,1);657}658}659}660661662int CV_InitUndistortRectifyMapTest::prepare_test_case(int test_case_idx)663{664RNG& rng = ts->get_rng();665int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );666667if (code <= 0)668return code;669670img_size.width = cvtest::randInt(rng) % MAX_X + 1;671img_size.height = cvtest::randInt(rng) % MAX_Y + 1;672673if (useCPlus)674{675mat_type = (cvtest::randInt(rng) % 2) == 0 ? CV_32FC1 : CV_16SC2;676if ((cvtest::randInt(rng) % 4) == 0)677mat_type = -1;678if ((cvtest::randInt(rng) % 4) == 0)679mat_type = CV_32FC2;680_mapx = 0;681_mapy = 0;682}683else684{685int typex = (cvtest::randInt(rng) % 2) == 0 ? CV_32FC1 : CV_16SC2;686//typex = CV_32FC1; ///!!!!!!!!!!!!!!!!687int typey = (typex == CV_32FC1) ? CV_32FC1 : CV_16UC1;688689_mapx = cvCreateMat(img_size.height,img_size.width,typex);690_mapy = cvCreateMat(img_size.height,img_size.width,typey);691692693}694695int dist_size = test_mat[INPUT][2].cols > test_mat[INPUT][2].rows ? test_mat[INPUT][2].cols : test_mat[INPUT][2].rows;696double cam[9] = {0,0,0,0,0,0,0,0,1};697vector<double> dist(dist_size);698vector<double> new_cam(test_mat[INPUT][4].cols * test_mat[INPUT][4].rows);699vector<Point2d> points(N_POINTS);700701Mat _camera(3,3,CV_64F,cam);702Mat _distort(test_mat[INPUT][2].size(),CV_64F,&dist[0]);703Mat _new_cam(test_mat[INPUT][4].size(),CV_64F,&new_cam[0]);704Mat _points(test_mat[INPUT][0].size(),CV_64FC2, &points[0]);705706//Generating points707for (int i=0;i<N_POINTS;i++)708{709points[i].x = cvtest::randReal(rng)*img_size.width;710points[i].y = cvtest::randReal(rng)*img_size.height;711}712713//Generating camera matrix714double sz = MAX(img_size.width,img_size.height);715double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;716cam[2] = (img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5;717cam[5] = (img_size.height - 1)*0.5 + cvtest::randReal(rng)*10 - 5;718cam[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);719cam[4] = aspect_ratio*cam[0];720721//Generating distortion coeffs722dist[0] = cvtest::randReal(rng)*0.06 - 0.03;723dist[1] = cvtest::randReal(rng)*0.06 - 0.03;724if( dist[0]*dist[1] > 0 )725dist[1] = -dist[1];726if( cvtest::randInt(rng)%4 != 0 )727{728dist[2] = cvtest::randReal(rng)*0.004 - 0.002;729dist[3] = cvtest::randReal(rng)*0.004 - 0.002;730if (dist_size > 4)731dist[4] = cvtest::randReal(rng)*0.004 - 0.002;732}733else734{735dist[2] = dist[3] = 0;736if (dist_size > 4)737dist[4] = 0;738}739740//Generating new camera matrix741_new_cam = Scalar::all(0);742new_cam[8] = 1;743744//new_cam[0] = cam[0];745//new_cam[4] = cam[4];746//new_cam[2] = cam[2];747//new_cam[5] = cam[5];748749new_cam[0] = cam[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[0]; //10%750new_cam[4] = cam[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[4]; //10%751new_cam[2] = cam[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.width; //15%752new_cam[5] = cam[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.height; //15%753754755//Generating R matrix756Mat _rot(3,3,CV_64F);757Mat rotation(1,3,CV_64F);758rotation.at<double>(0) = CV_PI/8*(cvtest::randReal(rng) - (double)0.5); // phi759rotation.at<double>(1) = CV_PI/8*(cvtest::randReal(rng) - (double)0.5); // ksi760rotation.at<double>(2) = CV_PI/3*(cvtest::randReal(rng) - (double)0.5); //khi761cvtest::Rodrigues(rotation, _rot);762763//cvSetIdentity(_rot);764//copying data765cvtest::convert( _points, test_mat[INPUT][0], test_mat[INPUT][0].type());766cvtest::convert( _camera, test_mat[INPUT][1], test_mat[INPUT][1].type());767cvtest::convert( _distort, test_mat[INPUT][2], test_mat[INPUT][2].type());768cvtest::convert( _rot, test_mat[INPUT][3], test_mat[INPUT][3].type());769cvtest::convert( _new_cam, test_mat[INPUT][4], test_mat[INPUT][4].type());770771zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;772zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;773zero_R = (cvtest::randInt(rng)%2) == 0 ? false : true;774775if (useCPlus)776{777camera_mat = test_mat[INPUT][1];778distortion_coeffs = test_mat[INPUT][2];779R = test_mat[INPUT][3];780new_camera_mat = test_mat[INPUT][4];781}782783return code;784}785786void CV_InitUndistortRectifyMapTest::prepare_to_validation(int/* test_case_idx*/)787{788#if 0789int dist_size = test_mat[INPUT][2].cols > test_mat[INPUT][2].rows ? test_mat[INPUT][2].cols : test_mat[INPUT][2].rows;790double cam[9] = {0,0,0,0,0,0,0,0,1};791double rot[9] = {1,0,0,0,1,0,0,0,1};792vector<double> dist(dist_size);793vector<double> new_cam(test_mat[INPUT][4].cols * test_mat[INPUT][4].rows);794vector<Point2d> points(N_POINTS);795vector<Point2d> r_points(N_POINTS);796//Run reference calculations797Mat ref_points(test_mat[INPUT][0].size(),CV_64FC2,&r_points[0]);798Mat _camera(3,3,CV_64F,cam);799Mat _rot(3,3,CV_64F,rot);800Mat _distort(test_mat[INPUT][2].size(),CV_64F,&dist[0]);801Mat _new_cam(test_mat[INPUT][4].size(),CV_64F,&new_cam[0]);802Mat _points(test_mat[INPUT][0].size(),CV_64FC2,&points[0]);803804cvtest::convert(test_mat[INPUT][1],_camera,_camera.type());805cvtest::convert(test_mat[INPUT][2],_distort,_distort.type());806cvtest::convert(test_mat[INPUT][3],_rot,_rot.type());807cvtest::convert(test_mat[INPUT][4],_new_cam,_new_cam.type());808809//Applying precalculated undistort rectify map810if (!useCPlus)811{812mapx = cv::Mat(_mapx);813mapy = cv::Mat(_mapy);814}815cv::Mat map1,map2;816cv::convertMaps(mapx,mapy,map1,map2,CV_32FC1);817CvMat _map1 = map1;818CvMat _map2 = map2;819const Point2d* sptr = (const Point2d*)test_mat[INPUT][0].data;820for( int i = 0;i < N_POINTS; i++ )821{822int u = saturate_cast<int>(sptr[i].x);823int v = saturate_cast<int>(sptr[i].y);824points[i].x = _map1.data.fl[v*_map1.cols + u];825points[i].y = _map2.data.fl[v*_map2.cols + u];826}827828//---829830cv::undistortPoints(_points, ref_points, _camera,831zero_distortion ? Mat() : _distort,832zero_R ? Mat::eye(3,3,CV_64F) : _rot,833zero_new_cam ? _camera : _new_cam);834//cvTsDistortPoints(&_points,&ref_points,&_camera,&_distort,&_rot,&_new_cam);835cvtest::convert(ref_points, test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].type());836cvtest::copy(test_mat[INPUT][0],test_mat[OUTPUT][0]);837838cvReleaseMat(&_mapx);839cvReleaseMat(&_mapy);840#else841int dist_size = test_mat[INPUT][2].cols > test_mat[INPUT][2].rows ? test_mat[INPUT][2].cols : test_mat[INPUT][2].rows;842double cam[9] = {0,0,0,0,0,0,0,0,1};843double rot[9] = {1,0,0,0,1,0,0,0,1};844double* dist = new double[dist_size ];845double* new_cam = new double[test_mat[INPUT][4].cols * test_mat[INPUT][4].rows];846double* points = new double[N_POINTS*2];847double* r_points = new double[N_POINTS*2];848//Run reference calculations849CvMat ref_points= cvMat(test_mat[INPUT][0].rows,test_mat[INPUT][0].cols,CV_64FC2,r_points);850CvMat _camera = cvMat(3,3,CV_64F,cam);851CvMat _rot = cvMat(3,3,CV_64F,rot);852CvMat _distort = cvMat(test_mat[INPUT][2].rows,test_mat[INPUT][2].cols,CV_64F,dist);853CvMat _new_cam = cvMat(test_mat[INPUT][4].rows,test_mat[INPUT][4].cols,CV_64F,new_cam);854CvMat _points= cvMat(test_mat[INPUT][0].rows,test_mat[INPUT][0].cols,CV_64FC2,points);855856CvMat _input1 = cvMat(test_mat[INPUT][1]);857CvMat _input2 = cvMat(test_mat[INPUT][2]);858CvMat _input3 = cvMat(test_mat[INPUT][3]);859CvMat _input4 = cvMat(test_mat[INPUT][4]);860861cvtest::convert(cvarrToMat(&_input1), cvarrToMat(&_camera), -1);862cvtest::convert(cvarrToMat(&_input2), cvarrToMat(&_distort), -1);863cvtest::convert(cvarrToMat(&_input3), cvarrToMat(&_rot), -1);864cvtest::convert(cvarrToMat(&_input4), cvarrToMat(&_new_cam), -1);865866//Applying precalculated undistort rectify map867if (!useCPlus)868{869mapx = cv::cvarrToMat(_mapx);870mapy = cv::cvarrToMat(_mapy);871}872cv::Mat map1,map2;873cv::convertMaps(mapx,mapy,map1,map2,CV_32FC1);874CvMat _map1 = cvMat(map1);875CvMat _map2 = cvMat(map2);876for (int i=0;i<N_POINTS;i++)877{878double u = test_mat[INPUT][0].ptr<double>()[2*i];879double v = test_mat[INPUT][0].ptr<double>()[2*i+1];880_points.data.db[2*i] = (double)_map1.data.fl[(int)v*_map1.cols+(int)u];881_points.data.db[2*i+1] = (double)_map2.data.fl[(int)v*_map2.cols+(int)u];882}883884//---885886cvUndistortPoints(&_points,&ref_points,&_camera,887zero_distortion ? 0 : &_distort, zero_R ? 0 : &_rot, zero_new_cam ? &_camera : &_new_cam);888//cvTsDistortPoints(&_points,&ref_points,&_camera,&_distort,&_rot,&_new_cam);889CvMat dst = cvMat(test_mat[REF_OUTPUT][0]);890cvtest::convert(cvarrToMat(&ref_points), cvarrToMat(&dst), -1);891892cvtest::copy(test_mat[INPUT][0],test_mat[OUTPUT][0]);893894delete[] dist;895delete[] new_cam;896delete[] points;897delete[] r_points;898cvReleaseMat(&_mapx);899cvReleaseMat(&_mapy);900#endif901}902903void CV_InitUndistortRectifyMapTest::run_func()904{905if (useCPlus)906{907cv::Mat input2,input3,input4;908input2 = zero_distortion ? cv::Mat() : test_mat[INPUT][2];909input3 = zero_R ? cv::Mat() : test_mat[INPUT][3];910input4 = zero_new_cam ? cv::Mat() : test_mat[INPUT][4];911cv::initUndistortRectifyMap(camera_mat,input2,input3,input4,img_size,mat_type,mapx,mapy);912}913else914{915CvMat input1 = cvMat(test_mat[INPUT][1]), input2, input3, input4;916if( !zero_distortion )917input2 = cvMat(test_mat[INPUT][2]);918if( !zero_R )919input3 = cvMat(test_mat[INPUT][3]);920if( !zero_new_cam )921input4 = cvMat(test_mat[INPUT][4]);922cvInitUndistortRectifyMap(&input1,923zero_distortion ? 0 : &input2,924zero_R ? 0 : &input3,925zero_new_cam ? 0 : &input4,926_mapx,_mapy);927}928}929930double CV_InitUndistortRectifyMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )931{932return 8;933}934935//////////////////////////////////////////////////////////////////////////////////////////////////////936937TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest test; test.safe_run(); }938TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); }939TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); }940941////////////////////////////// undistort /////////////////////////////////942943static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy,944Mat* mask=0, int interpolation=CV_INTER_LINEAR )945{946int x, y, k;947int drows = dst.rows, dcols = dst.cols;948int srows = src.rows, scols = src.cols;949const uchar* sptr0 = src.ptr();950int depth = src.depth(), cn = src.channels();951int elem_size = (int)src.elemSize();952int step = (int)(src.step / CV_ELEM_SIZE(depth));953int delta;954955if( interpolation != CV_INTER_CUBIC )956{957delta = 0;958scols -= 1; srows -= 1;959}960else961{962delta = 1;963scols = MAX(scols - 3, 0);964srows = MAX(srows - 3, 0);965}966967int scols1 = MAX(scols - 2, 0);968int srows1 = MAX(srows - 2, 0);969970if( mask )971*mask = Scalar::all(0);972973for( y = 0; y < drows; y++ )974{975uchar* dptr = dst.ptr(y);976const float* mx = mapx.ptr<float>(y);977const float* my = mapy.ptr<float>(y);978uchar* m = mask ? mask->ptr(y) : 0;979980for( x = 0; x < dcols; x++, dptr += elem_size )981{982float xs = mx[x];983float ys = my[x];984int ixs = cvFloor(xs);985int iys = cvFloor(ys);986987if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 ||988(unsigned)(iys - delta - 1) >= (unsigned)srows1 )989{990if( m )991m[x] = 1;992if( (unsigned)(ixs - delta) >= (unsigned)scols ||993(unsigned)(iys - delta) >= (unsigned)srows )994continue;995}996997xs -= ixs;998ys -= iys;9991000switch( depth )1001{1002case CV_8U:1003{1004const uchar* sptr = sptr0 + iys*step + ixs*cn;1005for( k = 0; k < cn; k++ )1006{1007float v00 = sptr[k];1008float v01 = sptr[cn + k];1009float v10 = sptr[step + k];1010float v11 = sptr[step + cn + k];10111012v00 = v00 + xs*(v01 - v00);1013v10 = v10 + xs*(v11 - v10);1014v00 = v00 + ys*(v10 - v00);1015dptr[k] = (uchar)cvRound(v00);1016}1017}1018break;1019case CV_16U:1020{1021const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn;1022for( k = 0; k < cn; k++ )1023{1024float v00 = sptr[k];1025float v01 = sptr[cn + k];1026float v10 = sptr[step + k];1027float v11 = sptr[step + cn + k];10281029v00 = v00 + xs*(v01 - v00);1030v10 = v10 + xs*(v11 - v10);1031v00 = v00 + ys*(v10 - v00);1032((ushort*)dptr)[k] = (ushort)cvRound(v00);1033}1034}1035break;1036case CV_32F:1037{1038const float* sptr = (const float*)sptr0 + iys*step + ixs*cn;1039for( k = 0; k < cn; k++ )1040{1041float v00 = sptr[k];1042float v01 = sptr[cn + k];1043float v10 = sptr[step + k];1044float v11 = sptr[step + cn + k];10451046v00 = v00 + xs*(v01 - v00);1047v10 = v10 + xs*(v11 - v10);1048v00 = v00 + ys*(v10 - v00);1049((float*)dptr)[k] = (float)v00;1050}1051}1052break;1053default:1054assert(0);1055}1056}1057}1058}10591060class CV_ImgWarpBaseTest : public cvtest::ArrayTest1061{1062public:1063CV_ImgWarpBaseTest( bool warp_matrix );10641065protected:1066int read_params( CvFileStorage* fs );1067int prepare_test_case( int test_case_idx );1068void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );1069void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );1070void fill_array( int test_case_idx, int i, int j, Mat& arr );10711072int interpolation;1073int max_interpolation;1074double spatial_scale_zoom, spatial_scale_decimate;1075};107610771078CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )1079{1080test_array[INPUT].push_back(NULL);1081if( warp_matrix )1082test_array[INPUT].push_back(NULL);1083test_array[INPUT_OUTPUT].push_back(NULL);1084test_array[REF_INPUT_OUTPUT].push_back(NULL);1085max_interpolation = 5;1086interpolation = 0;1087element_wise_relative_error = false;1088spatial_scale_zoom = 0.01;1089spatial_scale_decimate = 0.005;1090}109110921093int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )1094{1095int code = cvtest::ArrayTest::read_params( fs );1096return code;1097}109810991100void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )1101{1102cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );1103if( CV_MAT_DEPTH(type) == CV_32F )1104{1105low = Scalar::all(-10.);1106high = Scalar::all(10);1107}1108}110911101111void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx,1112vector<vector<Size> >& sizes, vector<vector<int> >& types )1113{1114RNG& rng = ts->get_rng();1115int depth = cvtest::randInt(rng) % 3;1116int cn = cvtest::randInt(rng) % 3 + 1;1117cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );1118depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F;1119cn += cn == 2;11201121types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);1122if( test_array[INPUT].size() > 1 )1123types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1;11241125interpolation = cvtest::randInt(rng) % max_interpolation;1126}112711281129void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr )1130{1131if( i != INPUT || j != 0 )1132cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );1133}11341135int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx )1136{1137int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );1138Mat& img = test_mat[INPUT][0];1139int i, j, cols = img.cols;1140int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);1141double scale = depth == CV_16U ? 1000. : 255.*0.5;1142double space_scale = spatial_scale_decimate;1143vector<float> buffer(img.cols*cn);11441145if( code <= 0 )1146return code;11471148if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&1149test_mat[INPUT_OUTPUT][0].rows >= img.rows )1150space_scale = spatial_scale_zoom;11511152for( i = 0; i < img.rows; i++ )1153{1154uchar* ptr = img.ptr(i);1155switch( cn )1156{1157case 1:1158for( j = 0; j < cols; j++ )1159buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale);1160break;1161case 2:1162for( j = 0; j < cols; j++ )1163{1164buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale);1165buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale);1166}1167break;1168case 3:1169for( j = 0; j < cols; j++ )1170{1171buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale);1172buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale);1173buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale);1174}1175break;1176case 4:1177for( j = 0; j < cols; j++ )1178{1179buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale);1180buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale);1181buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale);1182buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale);1183}1184break;1185default:1186assert(0);1187}11881189/*switch( depth )1190{1191case CV_8U:1192for( j = 0; j < cols*cn; j++ )1193ptr[j] = (uchar)cvRound(buffer[j]);1194break;1195case CV_16U:1196for( j = 0; j < cols*cn; j++ )1197((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]);1198break;1199case CV_32F:1200for( j = 0; j < cols*cn; j++ )1201((float*)ptr)[j] = (float)buffer[j];1202break;1203default:1204assert(0);1205}*/1206cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);1207cv::Mat dst(1, cols*cn, depth, ptr);1208src.convertTo(dst, dst.type());1209}12101211return code;1212}121312141215class CV_UndistortTest : public CV_ImgWarpBaseTest1216{1217public:1218CV_UndistortTest();12191220protected:1221void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );1222void run_func();1223int prepare_test_case( int test_case_idx );1224void prepare_to_validation( int /*test_case_idx*/ );1225double get_success_error_level( int test_case_idx, int i, int j );1226void fill_array( int test_case_idx, int i, int j, Mat& arr );12271228private:1229bool useCPlus;1230cv::Mat input0;1231cv::Mat input1;1232cv::Mat input2;1233cv::Mat input_new_cam;1234cv::Mat input_output;12351236bool zero_new_cam;1237bool zero_distortion;1238};123912401241CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false )1242{1243//spatial_scale_zoom = spatial_scale_decimate;1244test_array[INPUT].push_back(NULL);1245test_array[INPUT].push_back(NULL);1246test_array[INPUT].push_back(NULL);12471248spatial_scale_decimate = spatial_scale_zoom;1249}125012511252void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )1253{1254RNG& rng = ts->get_rng();1255CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );1256int type = types[INPUT][0];1257type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );1258types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type;1259types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;1260types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;1261sizes[INPUT][1] = cvSize(3,3);1262sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);1263types[INPUT][3] = types[INPUT][1];1264sizes[INPUT][3] = sizes[INPUT][1];1265interpolation = CV_INTER_LINEAR;1266}126712681269void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr )1270{1271if( i != INPUT )1272CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );1273}127412751276void CV_UndistortTest::run_func()1277{1278if (!useCPlus)1279{1280CvMat a = cvMat(test_mat[INPUT][1]), k = cvMat(test_mat[INPUT][2]);1281cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);1282}1283else1284{1285if (zero_distortion)1286{1287cv::undistort(input0,input_output,input1,cv::Mat());1288}1289else1290{1291cv::undistort(input0,input_output,input1,input2);1292}1293}1294}129512961297double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )1298{1299int depth = test_mat[INPUT][0].depth();1300return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;1301}130213031304int CV_UndistortTest::prepare_test_case( int test_case_idx )1305{1306RNG& rng = ts->get_rng();1307int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );13081309const Mat& src = test_mat[INPUT][0];1310double k[4], a[9] = {0,0,0,0,0,0,0,0,1};1311double new_cam[9] = {0,0,0,0,0,0,0,0,1};1312double sz = MAX(src.rows, src.cols);13131314Mat& _new_cam0 = test_mat[INPUT][3];1315Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam);1316Mat& _a0 = test_mat[INPUT][1];1317Mat _a(3,3,CV_64F,a);1318Mat& _k0 = test_mat[INPUT][2];1319Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);13201321if( code <= 0 )1322return code;13231324double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;1325a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;1326a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;1327a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);1328a[4] = aspect_ratio*a[0];1329k[0] = cvtest::randReal(rng)*0.06 - 0.03;1330k[1] = cvtest::randReal(rng)*0.06 - 0.03;1331if( k[0]*k[1] > 0 )1332k[1] = -k[1];1333if( cvtest::randInt(rng)%4 != 0 )1334{1335k[2] = cvtest::randReal(rng)*0.004 - 0.002;1336k[3] = cvtest::randReal(rng)*0.004 - 0.002;1337}1338else1339k[2] = k[3] = 0;13401341new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10%1342new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10%1343new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15%1344new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15%13451346_a.convertTo(_a0, _a0.depth());13471348zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;1349_k.convertTo(_k0, _k0.depth());13501351zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;1352_new_cam.convertTo(_new_cam0, _new_cam0.depth());13531354//Testing C++ code1355useCPlus = ((cvtest::randInt(rng) % 2)!=0);1356if (useCPlus)1357{1358input0 = test_mat[INPUT][0];1359input1 = test_mat[INPUT][1];1360input2 = test_mat[INPUT][2];1361input_new_cam = test_mat[INPUT][3];1362}13631364return code;1365}136613671368void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ )1369{1370if (useCPlus)1371{1372Mat& output = test_mat[INPUT_OUTPUT][0];1373input_output.convertTo(output, output.type());1374}1375Mat& src = test_mat[INPUT][0];1376Mat& dst = test_mat[REF_INPUT_OUTPUT][0];1377Mat& dst0 = test_mat[INPUT_OUTPUT][0];1378Mat mapx, mapy;1379cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy );1380Mat mask( dst.size(), CV_8U );1381test_remap( src, dst, mapx, mapy, &mask, interpolation );1382dst.setTo(Scalar::all(0), mask);1383dst0.setTo(Scalar::all(0), mask);1384}138513861387class CV_UndistortMapTest : public cvtest::ArrayTest1388{1389public:1390CV_UndistortMapTest();13911392protected:1393void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );1394void run_func();1395int prepare_test_case( int test_case_idx );1396void prepare_to_validation( int /*test_case_idx*/ );1397double get_success_error_level( int test_case_idx, int i, int j );1398void fill_array( int test_case_idx, int i, int j, Mat& arr );13991400private:1401bool dualChannel;1402};140314041405CV_UndistortMapTest::CV_UndistortMapTest()1406{1407test_array[INPUT].push_back(NULL);1408test_array[INPUT].push_back(NULL);1409test_array[OUTPUT].push_back(NULL);1410test_array[OUTPUT].push_back(NULL);1411test_array[REF_OUTPUT].push_back(NULL);1412test_array[REF_OUTPUT].push_back(NULL);14131414element_wise_relative_error = false;1415}141614171418void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )1419{1420RNG& rng = ts->get_rng();1421cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );1422int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;14231424Size sz = sizes[OUTPUT][0];1425types[INPUT][0] = types[INPUT][1] = depth;1426dualChannel = cvtest::randInt(rng)%2 == 0;1427types[OUTPUT][0] = types[OUTPUT][1] =1428types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F;1429sizes[INPUT][0] = cvSize(3,3);1430sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);14311432sz.width = MAX(sz.width,16);1433sz.height = MAX(sz.height,16);1434sizes[OUTPUT][0] = sizes[OUTPUT][1] =1435sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz;1436}143714381439void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )1440{1441if( i != INPUT )1442cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );1443}144414451446void CV_UndistortMapTest::run_func()1447{1448CvMat a = cvMat(test_mat[INPUT][0]), k = cvMat(test_mat[INPUT][1]);14491450if (!dualChannel )1451cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );1452else1453cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );1454}145514561457double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )1458{1459return 1e-3;1460}146114621463int CV_UndistortMapTest::prepare_test_case( int test_case_idx )1464{1465RNG& rng = ts->get_rng();1466int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );1467const Mat& mapx = test_mat[OUTPUT][0];1468double k[4], a[9] = {0,0,0,0,0,0,0,0,1};1469double sz = MAX(mapx.rows, mapx.cols);1470Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1];1471Mat _a(3,3,CV_64F,a);1472Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);14731474if( code <= 0 )1475return code;14761477double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;1478a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;1479a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;1480a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);1481a[4] = aspect_ratio*a[0];1482k[0] = cvtest::randReal(rng)*0.06 - 0.03;1483k[1] = cvtest::randReal(rng)*0.06 - 0.03;1484if( k[0]*k[1] > 0 )1485k[1] = -k[1];1486k[2] = cvtest::randReal(rng)*0.004 - 0.002;1487k[3] = cvtest::randReal(rng)*0.004 - 0.002;14881489_a.convertTo(_a0, _a0.depth());1490_k.convertTo(_k0, _k0.depth());14911492if (dualChannel)1493{1494test_mat[REF_OUTPUT][1] = Scalar::all(0);1495test_mat[OUTPUT][1] = Scalar::all(0);1496}14971498return code;1499}150015011502void CV_UndistortMapTest::prepare_to_validation( int )1503{1504Mat mapx, mapy;1505cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy );1506if( !dualChannel )1507{1508mapx.copyTo(test_mat[REF_OUTPUT][0]);1509mapy.copyTo(test_mat[REF_OUTPUT][1]);1510}1511else1512{1513Mat p[2] = {mapx, mapy};1514cv::merge(p, 2, test_mat[REF_OUTPUT][0]);1515}1516}15171518TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }1519TEST(Calib3d_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); }15201521}} // namespace152215231524