Move the sources to trunk
[opencv] / tests / cv / src / achesscorners.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, 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 documentation
24 //     and/or other materials provided with the distribution.
25 //
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.
28 //
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.
39 //
40 //M*/
41
42 #include "cvtest.h"
43
44 void show_points( IplImage* gray, CvPoint2D32f* u, int u_cnt, CvPoint2D32f* v, int v_cnt,
45                   CvSize etalon_size, int was_found )
46 {
47     CvSize size;
48     int i;
49
50     cvGetImageRawData( gray, 0, 0, &size );
51     
52     IplImage* rgb = cvCreateImage( size, 8, 3 );
53     cvMerge( gray, gray, gray, 0, rgb );
54
55     if( v )
56     {
57         for( i = 0; i < v_cnt; i++ )
58         {
59             cvCircle( rgb, cvPoint(cvRound(v[i].x), cvRound(v[i].y)), 3, CV_RGB(255,0,0), CV_FILLED);
60         }
61     }
62
63     if( u )
64     {
65         for( i = 0; i < u_cnt; i++ )
66         {
67             cvCircle( rgb, cvPoint(cvRound(u[i].x), cvRound(u[i].y)), 3, CV_RGB(0,255,0), CV_FILLED);
68         }
69     }
70
71     cvDrawChessboardCorners( rgb, etalon_size, v, v_cnt, was_found );
72
73     cvvNamedWindow( "test", 0 );
74     cvvShowImage( "test", rgb );
75
76     cvvWaitKey(0);
77 }
78
79
80 class CV_ChessboardDetectorTest : public CvTest
81 {
82 public:
83     CV_ChessboardDetectorTest();
84 protected:
85     void run(int);
86 };
87
88
89 CV_ChessboardDetectorTest::CV_ChessboardDetectorTest():
90     CvTest( "chessboard-detector", "cvFindChessboardCorners" )
91 {
92     support_testing_modes = CvTS::CORRECTNESS_CHECK_MODE;
93 }
94
95 /* ///////////////////// chess_corner_test ///////////////////////// */
96 void CV_ChessboardDetectorTest::run( int start_from )
97 {
98     int code = CvTS::OK;
99
100 #ifndef WRITE_POINTS    
101     const double rough_success_error_level = 2.5;
102     const double precise_success_error_level = 0.2;
103     double err = 0, max_rough_error = 0, max_precise_error = 0;
104 #endif
105
106     /* test parameters */
107     char   filepath[1000];
108     char   filename[1000];
109
110     CvMat*  _u = 0;
111     CvMat*  _v = 0;
112     CvPoint2D32f* u;
113     CvPoint2D32f* v;
114
115     IplImage* img = 0;
116     IplImage* gray = 0;
117     IplImage* thresh = 0;
118
119     int  idx, max_idx;
120     int  progress = 0;
121
122     sprintf( filepath, "%scameracalibration/", ts->get_data_path() );
123     sprintf( filename, "%schessboard_list.dat", filepath );
124     CvFileStorage* fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ );
125     CvFileNode* board_list = fs ? cvGetFileNodeByName( fs, 0, "boards" ) : 0;
126
127     if( !fs || !board_list || !CV_NODE_IS_SEQ(board_list->tag) ||
128         board_list->data.seq->total % 2 != 0 )
129     {
130         ts->printf( CvTS::LOG, "chessboard_list.dat can not be readed or is not valid" );
131         code = CvTS::FAIL_MISSING_TEST_DATA;
132         goto _exit_;
133     }
134
135     max_idx = board_list->data.seq->total/2;
136
137     for( idx = start_from; idx < max_idx; idx++ )
138     {
139         int etalon_count = -1;
140         int count = 0;
141         CvSize etalon_size = { -1, -1 };
142         int j, result;
143         
144         ts->update_context( this, idx-1, true );
145
146         /* read the image */
147         sprintf( filename, "%s%s", filepath,
148             cvReadString((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*2),"dummy.txt"));
149     
150         img = cvLoadImage( filename );
151         
152         if( !img )
153         {
154             ts->printf( CvTS::LOG, "one of chessboard images can't be read: %s", filename );
155             if( max_idx == 1 )
156             {
157                 code = CvTS::FAIL_MISSING_TEST_DATA;
158                 goto _exit_;
159             }
160             continue;
161         }
162
163         gray = cvCreateImage( cvSize( img->width, img->height ), IPL_DEPTH_8U, 1 );
164         thresh = cvCreateImage( cvSize( img->width, img->height ), IPL_DEPTH_8U, 1 );
165         cvCvtColor( img, gray, CV_BGR2GRAY );
166  
167         sprintf( filename, "%s%s", filepath,
168             cvReadString((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*2+1),"dummy.txt"));
169
170         _u = (CvMat*)cvLoad( filename );
171
172         if( _u == 0 )
173         {
174             if( idx == 0 )
175                 ts->printf( CvTS::LOG, "one of chessboard corner files can't be read: %s", filename ); 
176             if( max_idx == 1 )
177             {
178                 code = CvTS::FAIL_MISSING_TEST_DATA;
179                 goto _exit_;
180             }
181             continue;
182         }
183
184         etalon_size.width = _u->cols;
185         etalon_size.height = _u->rows;
186         etalon_count = etalon_size.width*etalon_size.height;
187
188         /* allocate additional buffers */
189         _v = cvCloneMat( _u );
190         count = etalon_count;
191
192         u = (CvPoint2D32f*)_u->data.fl;
193         v = (CvPoint2D32f*)_v->data.fl;
194
195         OPENCV_CALL( result = cvFindChessBoardCornerGuesses(
196                      gray, thresh, 0, etalon_size, v, &count ));
197
198         //show_points( gray, 0, etalon_count, v, count, etalon_size, result );
199         if( !result || count != etalon_count )
200         {
201             ts->printf( CvTS::LOG, "chess board is not found" );
202             code = CvTS::FAIL_INVALID_OUTPUT;
203             goto _exit_;
204         }
205
206 #ifndef WRITE_POINTS
207         err = 0;
208         for( j = 0; j < etalon_count; j++ )
209         {
210             double dx = fabs( v[j].x - u[j].x );
211             double dy = fabs( v[j].y - u[j].y );
212
213             dx = MAX( dx, dy );
214             if( dx > err )
215             {
216                 err = dx;
217                 if( err > rough_success_error_level )
218                 {
219                     ts->printf( CvTS::LOG, "bad accuracy of corner guesses" );
220                     code = CvTS::FAIL_BAD_ACCURACY;
221                     goto _exit_;
222                 }
223             }
224         }
225         max_rough_error = MAX( max_rough_error, err );
226 #endif
227         OPENCV_CALL( cvFindCornerSubPix( gray, v, count, cvSize( 5, 5 ), cvSize(-1,-1),
228                             cvTermCriteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,30,0.1)));
229         //show_points( gray, u + 1, etalon_count, v, count );
230
231 #ifndef WRITE_POINTS
232         err = 0;
233         for( j = 0; j < etalon_count; j++ )
234         {
235             double dx = fabs( v[j].x - u[j].x );
236             double dy = fabs( v[j].y - u[j].y );
237
238             dx = MAX( dx, dy );
239             if( dx > err )
240             {
241                 err = dx;
242                 if( err > precise_success_error_level )
243                 {
244                     ts->printf( CvTS::LOG, "bad accuracy of adjusted corners" ); 
245                     code = CvTS::FAIL_BAD_ACCURACY;
246                     goto _exit_;
247                 }
248             }
249         }
250         max_precise_error = MAX( max_precise_error, err );
251 #else
252         cvSave( filename, _v );
253 #endif
254         cvReleaseMat( &_u );
255         cvReleaseMat( &_v );
256         cvReleaseImage( &img );
257         cvReleaseImage( &gray );
258         cvReleaseImage( &thresh );
259         progress = update_progress( progress, idx-1, max_idx, 0 );
260     }
261
262 _exit_:
263
264     /* release occupied memory */
265     cvReleaseMat( &_u );
266     cvReleaseMat( &_v );
267     cvReleaseFileStorage( &fs );
268     cvReleaseImage( &img );
269     cvReleaseImage( &gray );
270     cvReleaseImage( &thresh );
271
272     if( code < 0 )
273         ts->set_failed_test_info( code );
274 }
275
276 CV_ChessboardDetectorTest chessboard_detector_test;
277
278 /* End of file. */