1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // 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 damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
45 class CV_ProjectPointsTest : public CvArrTest
48 CV_ProjectPointsTest();
51 int read_params( CvFileStorage* fs );
52 void fill_array( int test_case_idx, int i, int j, CvMat* arr );
53 int prepare_test_case( int test_case_idx );
54 void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
55 double get_success_error_level( int test_case_idx, int i, int j );
57 void prepare_to_validation( int );
63 CV_ProjectPointsTest::CV_ProjectPointsTest()
64 : CvArrTest( "3d-ProjectPoints", "cvProjectPoints2", "" )
66 test_array[INPUT].push(NULL); // rotation vector
67 test_array[OUTPUT].push(NULL); // rotation matrix
68 test_array[OUTPUT].push(NULL); // jacobian (J)
69 test_array[OUTPUT].push(NULL); // rotation vector (backward transform result)
70 test_array[OUTPUT].push(NULL); // inverse transform jacobian (J1)
71 test_array[OUTPUT].push(NULL); // J*J1 (or J1*J) == I(3x3)
72 test_array[REF_OUTPUT].push(NULL);
73 test_array[REF_OUTPUT].push(NULL);
74 test_array[REF_OUTPUT].push(NULL);
75 test_array[REF_OUTPUT].push(NULL);
76 test_array[REF_OUTPUT].push(NULL);
78 element_wise_relative_error = false;
79 calc_jacobians = false;
81 support_testing_modes = CvTS::CORRECTNESS_CHECK_MODE;
82 default_timing_param_names = 0;
86 int CV_ProjectPointsTest::read_params( CvFileStorage* fs )
88 int code = CvArrTest::read_params( fs );
93 void CV_ProjectPointsTest::get_test_array_types_and_sizes(
94 int /*test_case_idx*/, CvSize** sizes, int** types )
96 CvRNG* rng = ts->get_rng();
97 int depth = cvTsRandInt(rng) % 2 == 0 ? CV_32F : CV_64F;
100 code = cvTsRandInt(rng) % 3;
101 types[INPUT][0] = CV_MAKETYPE(depth, 1);
105 sizes[INPUT][0] = cvSize(1,1);
106 types[INPUT][0] = CV_MAKETYPE(depth, 3);
109 sizes[INPUT][0] = cvSize(3,1);
111 sizes[INPUT][0] = cvSize(1,3);
113 sizes[OUTPUT][0] = cvSize(3, 3);
114 types[OUTPUT][0] = CV_MAKETYPE(depth, 1);
116 types[OUTPUT][1] = CV_MAKETYPE(depth, 1);
118 if( cvTsRandInt(rng) % 2 )
119 sizes[OUTPUT][1] = cvSize(3,9);
121 sizes[OUTPUT][1] = cvSize(9,3);
123 types[OUTPUT][2] = types[INPUT][0];
124 sizes[OUTPUT][2] = sizes[INPUT][0];
126 types[OUTPUT][3] = types[OUTPUT][1];
127 sizes[OUTPUT][3] = cvSize(sizes[OUTPUT][1].height, sizes[OUTPUT][1].width);
129 types[OUTPUT][4] = types[OUTPUT][1];
130 sizes[OUTPUT][4] = cvSize(3,3);
132 calc_jacobians = 1;//cvTsRandInt(rng) % 3 != 0;
133 if( !calc_jacobians )
134 sizes[OUTPUT][1] = sizes[OUTPUT][3] = sizes[OUTPUT][4] = cvSize(0,0);
136 for( i = 0; i < 5; i++ )
138 types[REF_OUTPUT][i] = types[OUTPUT][i];
139 sizes[REF_OUTPUT][i] = sizes[OUTPUT][i];
144 double CV_ProjectPointsTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int j )
146 return j == 4 ? 1e-2 : 1e-2;
150 void CV_ProjectPointsTest::fill_array( int /*test_case_idx*/, int /*i*/, int /*j*/, CvMat* arr )
152 double r[3], theta0, theta1, f;
153 CvMat _r = cvMat( arr->rows, arr->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(arr->type)), r );
154 CvRNG* rng = ts->get_rng();
156 r[0] = cvTsRandReal(rng)*CV_PI*2;
157 r[1] = cvTsRandReal(rng)*CV_PI*2;
158 r[2] = cvTsRandReal(rng)*CV_PI*2;
160 theta0 = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
161 theta1 = fmod(theta0, CV_PI*2);
164 theta1 = -(CV_PI*2 - theta1);
166 f = theta1/(theta0 ? theta0 : 1);
171 cvTsConvert( &_r, arr );
175 int CV_ProjectPointsTest::prepare_test_case( int test_case_idx )
177 int code = CvArrTest::prepare_test_case( test_case_idx );
182 void CV_ProjectPointsTest::run_func()
184 CvMat *v2m_jac = 0, *m2v_jac = 0;
187 v2m_jac = &test_mat[OUTPUT][1];
188 m2v_jac = &test_mat[OUTPUT][3];
191 cvProjectPoints2( &test_mat[INPUT][0], &test_mat[OUTPUT][0], v2m_jac );
192 cvProjectPoints2( &test_mat[OUTPUT][0], &test_mat[OUTPUT][2], m2v_jac );
196 void CV_ProjectPointsTest::prepare_to_validation( int /*test_case_idx*/ )
198 const CvMat* vec = &test_mat[INPUT][0];
199 CvMat* m = &test_mat[REF_OUTPUT][0];
200 CvMat* vec2 = &test_mat[REF_OUTPUT][2];
201 CvMat* v2m_jac = 0, *m2v_jac = 0;
202 double theta0, theta1;
206 v2m_jac = &test_mat[REF_OUTPUT][1];
207 m2v_jac = &test_mat[REF_OUTPUT][3];
211 cvTsProjectPoints( vec, m, v2m_jac );
212 cvTsProjectPoints( m, vec2, m2v_jac );
213 cvTsCopy( vec, vec2 );
215 theta0 = cvNorm( vec2, 0, CV_L2 );
216 theta1 = fmod( theta0, CV_PI*2 );
219 theta1 = -(CV_PI*2 - theta1);
220 cvScale( vec2, vec2, theta1/(theta0 ? theta0 : 1) );
224 //cvInvert( v2m_jac, m2v_jac, CV_SVD );
225 if( cvNorm(&test_mat[OUTPUT][3],0,CV_C) < 1000 )
227 cvTsGEMM( &test_mat[OUTPUT][1], &test_mat[OUTPUT][3],
228 1, 0, 0, &test_mat[OUTPUT][4],
229 v2m_jac->rows == 3 ? 0 : CV_GEMM_A_T + CV_GEMM_B_T );
233 cvTsSetIdentity( &test_mat[OUTPUT][4], cvScalarAll(1.) );
234 cvTsCopy( &test_mat[REF_OUTPUT][2], &test_mat[OUTPUT][2] );
236 cvTsSetIdentity( &test_mat[REF_OUTPUT][4], cvScalarAll(1.) );
241 CV_ProjectPointsTest ProjectPoints_test;
247 class CV_CameraCalibrationTest : public CvTest
250 CV_CameraCalibrationTest();
251 ~CV_CameraCalibrationTest();
253 //int write_default_params(CvFileStorage* fs);
256 //int read_params( CvFileStorage* fs );
257 int compare(double* val, double* ref_val, int len,
258 double eps, const char* param_name);
264 CV_CameraCalibrationTest::CV_CameraCalibrationTest():
265 CvTest( "calibratecamera", "cvCalibrateCamera2" )
267 support_testing_modes = CvTS::CORRECTNESS_CHECK_MODE;
271 CV_CameraCalibrationTest::~CV_CameraCalibrationTest()
277 void CV_CameraCalibrationTest::clear()
283 int CV_CameraCalibrationTest::compare(double* val, double* ref_val, int len,
284 double eps, const char* param_name )
286 return cvTsCmpEps2_64f( ts, val, ref_val, len, eps, param_name );
289 void CV_CameraCalibrationTest::run( int start_from )
299 CvPoint2D64d* imagePoints;
300 CvPoint3D64d* objectPoints;
301 CvPoint2D64d* reprojectPoints;
303 CvVect64d transVects;
306 CvVect64d goodTransVects;
307 CvMatr64d goodRotMatrs;
309 double cameraMatrix[3*3];
310 double distortion[4];
312 double goodDistortion[4];
322 char i_dat_file[100];
338 sprintf( filepath, "%scameracalibration/", ts->get_data_path() );
339 sprintf( filename, "%sdatafiles.txt", filepath );
340 datafile = fopen( filename, "r" );
343 ts->printf( CvTS::LOG, "Could not open file with list of test files: %s\n", filename );
344 code = CvTS::FAIL_MISSING_TEST_DATA;
348 fscanf(datafile,"%d",&numTests);
350 for( currTest = start_from; currTest < numTests; currTest++ )
352 fscanf(datafile,"%s",i_dat_file);
353 sprintf(filename, "%s%s", filepath, i_dat_file);
354 file = fopen(filename,"r");
356 ts->update_context( this, currTest, true );
360 ts->printf( CvTS::LOG,
361 "Can't open current test file: %s\n",filename);
364 code = CvTS::FAIL_MISSING_TEST_DATA;
367 continue; // if there is more than one test, just skip the test
370 fscanf(file,"%d %d\n",&(imageSize.width),&(imageSize.height));
371 if( imageSize.width <= 0 || imageSize.height <= 0 )
373 ts->printf( CvTS::LOG, "Image size in test file is incorrect\n" );
374 code = CvTS::FAIL_INVALID_TEST_DATA;
378 /* Read etalon size */
379 fscanf(file,"%d %d\n",&(etalonSize.width),&(etalonSize.height));
380 if( etalonSize.width <= 0 || etalonSize.height <= 0 )
382 ts->printf( CvTS::LOG, "Pattern size in test file is incorrect\n" );
383 code = CvTS::FAIL_INVALID_TEST_DATA;
387 numPoints = etalonSize.width * etalonSize.height;
389 /* Read number of images */
390 fscanf(file,"%d\n",&numImages);
393 ts->printf( CvTS::LOG, "Number of images in test file is incorrect\n");
394 code = CvTS::FAIL_INVALID_TEST_DATA;
398 /* Need to allocate memory */
399 imagePoints = (CvPoint2D64d*)cvAlloc( numPoints *
400 numImages * sizeof(CvPoint2D64d));
402 objectPoints = (CvPoint3D64d*)cvAlloc( numPoints *
403 numImages * sizeof(CvPoint3D64d));
405 reprojectPoints = (CvPoint2D64d*)cvAlloc( numPoints *
406 numImages * sizeof(CvPoint2D64d));
408 /* Alloc memory for numbers */
409 numbers = (int*)cvAlloc( numImages * sizeof(int));
411 /* Fill it by numbers of points of each image*/
412 for( currImage = 0; currImage < numImages; currImage++ )
414 numbers[currImage] = etalonSize.width * etalonSize.height;
417 /* Allocate memory for translate vectors and rotmatrixs*/
418 transVects = (CvVect64d)cvAlloc(3 * 1 * numImages * sizeof(double));
419 rotMatrs = (CvMatr64d)cvAlloc(3 * 3 * numImages * sizeof(double));
421 goodTransVects = (CvVect64d)cvAlloc(3 * 1 * numImages * sizeof(double));
422 goodRotMatrs = (CvMatr64d)cvAlloc(3 * 3 * numImages * sizeof(double));
424 /* Read object points */
425 i = 0;/* shift for current point */
426 for( currImage = 0; currImage < numImages; currImage++ )
428 for( currPoint = 0; currPoint < numPoints; currPoint++ )
431 fscanf(file,"%lf %lf %lf\n",&x,&y,&z);
433 (objectPoints+i)->x = x;
434 (objectPoints+i)->y = y;
435 (objectPoints+i)->z = z;
440 /* Read image points */
441 i = 0;/* shift for current point */
442 for( currImage = 0; currImage < numImages; currImage++ )
444 for( currPoint = 0; currPoint < numPoints; currPoint++ )
447 fscanf(file,"%lf %lf\n",&x,&y);
449 (imagePoints+i)->x = x;
450 (imagePoints+i)->y = y;
455 /* Read good data computed before */
458 double goodFcx,goodFcy;
459 fscanf(file,"%lf %lf",&goodFcx,&goodFcy);
461 /* Principal points */
462 double goodCx,goodCy;
463 fscanf(file,"%lf %lf",&goodCx,&goodCy);
465 /* Read distortion */
467 fscanf(file,"%lf",goodDistortion+0);
468 fscanf(file,"%lf",goodDistortion+1);
469 fscanf(file,"%lf",goodDistortion+2);
470 fscanf(file,"%lf",goodDistortion+3);
472 /* Read good Rot matrixes */
473 for( currImage = 0; currImage < numImages; currImage++ )
475 for( i = 0; i < 3; i++ )
476 for( j = 0; j < 3; j++ )
477 fscanf(file, "%lf", goodRotMatrs + currImage * 9 + j * 3 + i);
480 /* Read good Trans vectors */
481 for( currImage = 0; currImage < numImages; currImage++ )
483 for( i = 0; i < 3; i++ )
484 fscanf(file, "%lf", goodTransVects + currImage * 3 + i);
488 //CV_CALIB_FIX_PRINCIPAL_POINT +
489 //CV_CALIB_ZERO_TANGENT_DIST +
490 //CV_CALIB_FIX_ASPECT_RATIO +
491 //CV_CALIB_USE_INTRINSIC_GUESS +
493 memset( cameraMatrix, 0, 9*sizeof(cameraMatrix[0]) );
494 cameraMatrix[0] = cameraMatrix[4] = 807.;
495 cameraMatrix[2] = (imageSize.width - 1)*0.5;
496 cameraMatrix[5] = (imageSize.height - 1)*0.5;
497 cameraMatrix[8] = 1.;
499 /* Now we can calibrate camera */
500 cvCalibrateCamera_64d( numImages,
511 /* ---- Reproject points to the image ---- */
512 for( currImage = 0; currImage < numImages; currImage++ )
514 int numPoints = etalonSize.width * etalonSize.height;
515 cvProjectPointsSimple( numPoints,
516 objectPoints + currImage * numPoints,
517 rotMatrs + currImage * 9,
518 transVects + currImage * 3,
521 reprojectPoints + currImage * numPoints);
525 /* ----- Compute reprojection error ----- */
529 double meanDx,meanDy;
535 for( currImage = 0; currImage < numImages; currImage++ )
537 for( currPoint = 0; currPoint < etalonSize.width * etalonSize.height; currPoint++ )
539 rx = reprojectPoints[i].x;
540 ry = reprojectPoints[i].y;
541 dx = rx - imagePoints[i].x;
542 dy = ry - imagePoints[i].y;
559 meanDx /= numImages * etalonSize.width * etalonSize.height;
560 meanDy /= numImages * etalonSize.width * etalonSize.height;
562 /* ========= Compare parameters ========= */
564 /* ----- Compare focal lengths ----- */
565 code = compare(cameraMatrix+0,&goodFcx,1,0.01,"fx");
569 code = compare(cameraMatrix+4,&goodFcy,1,0.01,"fy");
573 /* ----- Compare principal points ----- */
574 code = compare(cameraMatrix+2,&goodCx,1,0.01,"cx");
578 code = compare(cameraMatrix+5,&goodCy,1,0.01,"cy");
582 /* ----- Compare distortion ----- */
583 code = compare(distortion,goodDistortion,4,0.01,"[k1,k2,p1,p2]");
587 /* ----- Compare rot matrixs ----- */
588 code = compare(rotMatrs,goodRotMatrs, 9*numImages,0.05,"rotation matrices");
592 /* ----- Compare rot matrixs ----- */
593 code = compare(transVects,goodTransVects, 3*numImages,0.05,"translation vectors");
599 ts->printf( CvTS::LOG,
600 "Error in reprojection maxDx=%f > 1.0\n",maxDx);
601 code = CvTS::FAIL_BAD_ACCURACY; goto _exit_;
606 ts->printf( CvTS::LOG,
607 "Error in reprojection maxDy=%f > 1.0\n",maxDy);
608 code = CvTS::FAIL_BAD_ACCURACY; goto _exit_;
611 progress = update_progress( progress, currTest, numTests, 0 );
613 cvFree(&imagePoints);
614 cvFree(&objectPoints);
615 cvFree(&reprojectPoints);
620 cvFree(&goodTransVects);
621 cvFree(&goodRotMatrs);
635 /* Free all allocated memory */
636 cvFree(&imagePoints);
637 cvFree(&objectPoints);
638 cvFree(&reprojectPoints);
643 cvFree(&goodTransVects);
644 cvFree(&goodRotMatrs);
647 ts->set_failed_test_info( code );
650 CV_CameraCalibrationTest calibrate_test;