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.
44 void show_points( IplImage* gray, CvPoint2D32f* u, int u_cnt, CvPoint2D32f* v, int v_cnt,
45 CvSize pattern_size, int was_found )
50 cvGetImageRawData( gray, 0, 0, &size );
52 IplImage* rgb = cvCreateImage( size, 8, 3 );
53 cvMerge( gray, gray, gray, 0, rgb );
57 for( i = 0; i < v_cnt; i++ )
59 cvCircle( rgb, cvPoint(cvRound(v[i].x), cvRound(v[i].y)), 3, CV_RGB(255,0,0), CV_FILLED);
65 for( i = 0; i < u_cnt; i++ )
67 cvCircle( rgb, cvPoint(cvRound(u[i].x), cvRound(u[i].y)), 3, CV_RGB(0,255,0), CV_FILLED);
71 cvDrawChessboardCorners( rgb, pattern_size, v, v_cnt, was_found );
73 cvvNamedWindow( "test", 0 );
74 cvvShowImage( "test", rgb );
80 class CV_ChessboardDetectorTest : public CvTest
83 CV_ChessboardDetectorTest();
89 CV_ChessboardDetectorTest::CV_ChessboardDetectorTest():
90 CvTest( "chessboard-detector", "cvFindChessboardCorners" )
92 support_testing_modes = CvTS::CORRECTNESS_CHECK_MODE;
95 /* ///////////////////// chess_corner_test ///////////////////////// */
96 void CV_ChessboardDetectorTest::run( int start_from )
100 //#define WRITE_POINTS 1
102 const double rough_success_error_level = 2.5;
103 const double precise_success_error_level = 2;
104 double err = 0, max_rough_error = 0, max_precise_error = 0;
107 /* test parameters */
118 IplImage* thresh = 0;
123 sprintf( filepath, "%scameracalibration/", ts->get_data_path() );
124 sprintf( filename, "%schessboard_list.dat", filepath );
125 CvFileStorage* fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ );
126 CvFileNode* board_list = fs ? cvGetFileNodeByName( fs, 0, "boards" ) : 0;
128 if( !fs || !board_list || !CV_NODE_IS_SEQ(board_list->tag) ||
129 board_list->data.seq->total % 2 != 0 )
131 ts->printf( CvTS::LOG, "chessboard_list.dat can not be readed or is not valid" );
132 code = CvTS::FAIL_MISSING_TEST_DATA;
136 max_idx = board_list->data.seq->total/2;
138 for( idx = start_from; idx < max_idx; idx++ )
142 CvSize pattern_size = { -1, -1 };
145 ts->update_context( this, idx-1, true );
148 sprintf( filename, "%s%s", filepath,
149 cvReadString((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*2),"dummy.txt"));
151 img = cvLoadImage( filename );
155 ts->printf( CvTS::LOG, "one of chessboard images can't be read: %s", filename );
158 code = CvTS::FAIL_MISSING_TEST_DATA;
164 gray = cvCreateImage( cvSize( img->width, img->height ), IPL_DEPTH_8U, 1 );
165 thresh = cvCreateImage( cvSize( img->width, img->height ), IPL_DEPTH_8U, 1 );
166 cvCvtColor( img, gray, CV_BGR2GRAY );
168 sprintf( filename, "%s%s", filepath,
169 cvReadString((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*2+1),"dummy.txt"));
171 _u = (CvMat*)cvLoad( filename );
176 ts->printf( CvTS::LOG, "one of chessboard corner files can't be read: %s", filename );
179 code = CvTS::FAIL_MISSING_TEST_DATA;
185 pattern_size.width = _u->cols;
186 pattern_size.height = _u->rows;
187 count0 = pattern_size.width*pattern_size.height;
189 /* allocate additional buffers */
190 _v = cvCloneMat( _u );
193 u = (CvPoint2D32f*)_u->data.fl;
194 v = (CvPoint2D32f*)_v->data.fl;
196 OPENCV_CALL( result = cvFindChessboardCorners(
197 gray, pattern_size, v, &count, 7 ));
199 //show_points( gray, 0, count0, v, count, pattern_size, result );
200 if( !result || count != count0 )
202 ts->printf( CvTS::LOG, "chess board is not found" );
203 code = CvTS::FAIL_INVALID_OUTPUT;
209 for( k = 0; k < 2; k++ )
212 for( j = 0; j < count0; j++ )
214 int j1 = k == 0 ? j : count0 - j - 1;
215 double dx = fabs( v[j].x - u[j1].x );
216 double dy = fabs( v[j].y - u[j1].y );
222 err = MIN(err, err1);
224 if( err > rough_success_error_level )
226 ts->printf( CvTS::LOG, "bad accuracy of corner guesses" );
227 code = CvTS::FAIL_BAD_ACCURACY;
231 max_rough_error = MAX( max_rough_error, err );
233 OPENCV_CALL( cvFindCornerSubPix( gray, v, count, cvSize( 5, 5 ), cvSize(-1,-1),
234 cvTermCriteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,30,0.1)));
235 //show_points( gray, u + 1, count0, v, count, pattern_size, result );
239 for( k = 0; k < 2; k++ )
242 for( j = 0; j < count0; j++ )
244 int j1 = k == 0 ? j : count0 - j - 1;
245 double dx = fabs( v[j].x - u[j1].x );
246 double dy = fabs( v[j].y - u[j1].y );
252 err = MIN(err, err1);
254 if( err > precise_success_error_level )
256 ts->printf( CvTS::LOG, "bad accuracy of adjusted corners" );
257 code = CvTS::FAIL_BAD_ACCURACY;
260 max_precise_error = MAX( max_precise_error, err );
262 cvSave( filename, _v );
266 cvReleaseImage( &img );
267 cvReleaseImage( &gray );
268 cvReleaseImage( &thresh );
269 progress = update_progress( progress, idx-1, max_idx, 0 );
274 /* release occupied memory */
277 cvReleaseFileStorage( &fs );
278 cvReleaseImage( &img );
279 cvReleaseImage( &gray );
280 cvReleaseImage( &thresh );
283 ts->set_failed_test_info( code );
286 CV_ChessboardDetectorTest chessboard_detector_test;