Performance testing branch is merged back into trunk
[profile/ivi/opencv.git] / modules / ts / include / opencv2 / ts / ts.hpp
1 #ifndef __OPENCV_GTESTCV_HPP__
2 #define __OPENCV_GTESTCV_HPP__
3
4 #ifndef GTEST_CREATE_SHARED_LIBRARY
5 #define GTEST_LINKED_AS_SHARED_LIBRARY 1
6 #endif
7
8 #ifdef ANDROID
9 # include <android/api-level.h>
10 # define GTEST_HAS_CLONE (__ANDROID_API__ > 7)
11 # define GTEST_HAS_POSIX_RE (__ANDROID_API__ > 7)
12 # define GTEST_HAS_STD_WSTRING _GLIBCXX_USE_WCHAR_T
13 #endif
14
15 #include <stdarg.h> // for va_list
16
17 #if _MSC_VER >= 1200
18 #pragma warning( disable: 4251 4275 4355 4127 )
19 #endif
20
21 #include "opencv2/ts/ts_gtest.h"
22 #include "opencv2/core/core.hpp"
23
24 namespace cvtest
25 {
26
27 using std::vector;
28 using std::string;
29 using cv::RNG;
30 using cv::Mat;
31 using cv::Scalar;
32 using cv::Size;
33 using cv::Point;
34 using cv::Rect;
35
36 class CV_EXPORTS TS;
37     
38 CV_EXPORTS int64 readSeed(const char* str);
39     
40 CV_EXPORTS void randUni( RNG& rng, Mat& a, const Scalar& param1, const Scalar& param2 );
41
42 inline unsigned randInt( RNG& rng )
43 {
44     return (unsigned)rng;
45 }
46
47 inline  double randReal( RNG& rng )
48 {
49     return (double)rng;
50 }
51     
52     
53 CV_EXPORTS const char* getTypeName( int type );
54 CV_EXPORTS int typeByName( const char* type_name );
55
56 CV_EXPORTS string vec2str(const string& sep, const int* v, size_t nelems);
57     
58 inline int clipInt( int val, int min_val, int max_val )
59 {
60     if( val < min_val )
61         val = min_val;
62     if( val > max_val )
63         val = max_val;
64     return val;
65 }
66
67 CV_EXPORTS double getMinVal(int depth);
68 CV_EXPORTS double getMaxVal(int depth);
69     
70 CV_EXPORTS Size randomSize(RNG& rng, double maxSizeLog);
71 CV_EXPORTS void randomSize(RNG& rng, int minDims, int maxDims, double maxSizeLog, vector<int>& sz);    
72 CV_EXPORTS int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels);
73 CV_EXPORTS Mat randomMat(RNG& rng, Size size, int type, double minVal, double maxVal, bool useRoi);
74 CV_EXPORTS Mat randomMat(RNG& rng, const vector<int>& size, int type, double minVal, double maxVal, bool useRoi);
75 CV_EXPORTS void add(const Mat& a, double alpha, const Mat& b, double beta,
76                       Scalar gamma, Mat& c, int ctype, bool calcAbs=false);
77 CV_EXPORTS void multiply(const Mat& a, const Mat& b, Mat& c, double alpha=1);
78 CV_EXPORTS void divide(const Mat& a, const Mat& b, Mat& c, double alpha=1);
79
80 CV_EXPORTS void convert(const Mat& src, Mat& dst, int dtype, double alpha=1, double beta=0);
81 CV_EXPORTS void copy(const Mat& src, Mat& dst, const Mat& mask=Mat(), bool invertMask=false);
82 CV_EXPORTS void set(Mat& dst, const Scalar& gamma, const Mat& mask=Mat());
83     
84 // working with multi-channel arrays
85 CV_EXPORTS void extract( const Mat& a, Mat& plane, int coi );
86 CV_EXPORTS void insert( const Mat& plane, Mat& a, int coi );
87
88 // checks that the array does not have NaNs and/or Infs and all the elements are
89 // within [min_val,max_val). idx is the index of the first "bad" element.
90 CV_EXPORTS int check( const Mat& data, double min_val, double max_val, vector<int>* idx );
91     
92 // modifies values that are close to zero
93 CV_EXPORTS void  patchZeros( Mat& mat, double level );
94     
95 CV_EXPORTS void transpose(const Mat& src, Mat& dst);
96 CV_EXPORTS void erode(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
97                       int borderType=IPL_BORDER_CONSTANT, const Scalar& borderValue=Scalar());
98 CV_EXPORTS void dilate(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
99                        int borderType=IPL_BORDER_CONSTANT, const Scalar& borderValue=Scalar());
100 CV_EXPORTS void filter2D(const Mat& src, Mat& dst, int ddepth, const Mat& kernel,
101                          Point anchor, double delta, int borderType,
102                          const Scalar& borderValue=Scalar());
103 CV_EXPORTS void copyMakeBorder(const Mat& src, Mat& dst, int top, int bottom, int left, int right,
104                                int borderType, const Scalar& borderValue=Scalar());
105 CV_EXPORTS Mat calcSobelKernel2D( int dx, int dy, int apertureSize, int origin=0 );
106 CV_EXPORTS Mat calcLaplaceKernel2D( int aperture_size );
107     
108 CV_EXPORTS void initUndistortMap( const Mat& a, const Mat& k, Size sz, Mat& mapx, Mat& mapy );
109     
110 CV_EXPORTS void minMaxLoc(const Mat& src, double* minval, double* maxval,
111                           vector<int>* minloc, vector<int>* maxloc, const Mat& mask=Mat());
112 CV_EXPORTS double norm(const Mat& src, int normType, const Mat& mask=Mat());
113 CV_EXPORTS double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask=Mat());
114 CV_EXPORTS Scalar mean(const Mat& src, const Mat& mask=Mat());
115     
116 CV_EXPORTS bool cmpUlps(const Mat& data, const Mat& refdata, int expMaxDiff, double* realMaxDiff, vector<int>* idx);
117     
118 // compares two arrays. max_diff is the maximum actual difference,
119 // success_err_level is maximum allowed difference, idx is the index of the first
120 // element for which difference is >success_err_level
121 // (or index of element with the maximum difference)
122 CV_EXPORTS int cmpEps( const Mat& data, const Mat& refdata, double* max_diff,
123                        double success_err_level, vector<int>* idx,
124                        bool element_wise_relative_error );
125     
126 // a wrapper for the previous function. in case of error prints the message to log file.
127 CV_EXPORTS int cmpEps2( TS* ts, const Mat& data, const Mat& refdata, double success_err_level,
128                         bool element_wise_relative_error, const char* desc );
129     
130 CV_EXPORTS int cmpEps2_64f( TS* ts, const double* val, const double* refval, int len,
131                         double eps, const char* param_name );
132     
133 CV_EXPORTS void logicOp(const Mat& src1, const Mat& src2, Mat& dst, char c);
134 CV_EXPORTS void logicOp(const Mat& src, const Scalar& s, Mat& dst, char c);
135 CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
136 CV_EXPORTS void min(const Mat& src, double s, Mat& dst);    
137 CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
138 CV_EXPORTS void max(const Mat& src, double s, Mat& dst);    
139     
140 CV_EXPORTS void compare(const Mat& src1, const Mat& src2, Mat& dst, int cmpop);
141 CV_EXPORTS void compare(const Mat& src, double s, Mat& dst, int cmpop);    
142 CV_EXPORTS void gemm(const Mat& src1, const Mat& src2, double alpha,
143                      const Mat& src3, double beta, Mat& dst, int flags);
144     CV_EXPORTS void transform( const Mat& src, Mat& dst, const Mat& transmat, const Mat& shift );
145 CV_EXPORTS double crossCorr(const Mat& src1, const Mat& src2);
146
147 struct CV_EXPORTS MatInfo
148 {
149     MatInfo(const Mat& _m) : m(&_m) {}
150     const Mat* m;
151 };
152
153 CV_EXPORTS std::ostream& operator << (std::ostream& out, const MatInfo& m);    
154     
155 struct CV_EXPORTS MatComparator
156 {
157 public:
158     MatComparator(double maxdiff, int context);
159     
160     ::testing::AssertionResult operator()(const char* expr1, const char* expr2,
161                                           const Mat& m1, const Mat& m2);
162     
163     double maxdiff;
164     double realmaxdiff;
165     vector<int> loc0;
166     int context;
167 };
168
169
170
171 class BaseTest;
172 class TS;
173
174 class CV_EXPORTS BaseTest
175 {
176 public:
177     // constructor(s) and destructor
178     BaseTest();
179     virtual ~BaseTest();
180
181     // the main procedure of the test
182     virtual void run( int start_from );
183
184     // the wrapper for run that cares of exceptions
185     virtual void safe_run( int start_from=0 );
186
187     const string& get_name() const { return name; }
188
189     // returns true if and only if the different test cases do not depend on each other
190     // (so that test system could get right to a problematic test case)
191     virtual bool can_do_fast_forward();
192
193     // deallocates all the memory.
194     // called by init() (before initialization) and by the destructor
195     virtual void clear();
196
197 protected:
198     int test_case_count; // the total number of test cases
199
200     // read test params
201     virtual int read_params( CvFileStorage* fs );
202
203     // returns the number of tests or -1 if it is unknown a-priori
204     virtual int get_test_case_count();
205
206     // prepares data for the next test case. rng seed is updated by the function
207     virtual int prepare_test_case( int test_case_idx );
208
209     // checks if the test output is valid and accurate
210     virtual int validate_test_results( int test_case_idx );
211
212     // calls the tested function. the method is called from run_test_case()
213     virtual void run_func(); // runs tested func(s)
214
215     // updates progress bar
216     virtual int update_progress( int progress, int test_case_idx, int count, double dt );
217
218     // finds test parameter
219     const CvFileNode* find_param( CvFileStorage* fs, const char* param_name );
220
221     // name of the test (it is possible to locate a test by its name)
222     string name;
223
224     // pointer to the system that includes the test
225     TS* ts;
226 };
227
228
229 /*****************************************************************************************\
230 *                               Information about a failed test                           *
231 \*****************************************************************************************/
232
233 struct TestInfo
234 {
235     TestInfo();
236     
237     // pointer to the test
238     BaseTest* test;
239
240     // failure code (CV_FAIL*)
241     int code;
242
243     // seed value right before the data for the failed test case is prepared.
244     uint64 rng_seed;
245     
246     // seed value right before running the test
247     uint64 rng_seed0;
248
249     // index of test case, can be then passed to BaseTest::proceed_to_test_case()
250     int test_case_idx;
251 };
252
253 /*****************************************************************************************\
254 *                                 Base Class for test system                              *
255 \*****************************************************************************************/
256
257 // common parameters:
258 struct CV_EXPORTS TSParams
259 {
260     TSParams();
261     
262     // RNG seed, passed to and updated by every test executed.
263     uint64 rng_seed;
264     
265     // whether to use IPP, MKL etc. or not
266     bool use_optimized;
267     
268     // extensivity of the tests, scale factor for test_case_count
269     double test_case_count_scale;
270 };
271
272     
273 class CV_EXPORTS TS
274 {
275 public:
276     // constructor(s) and destructor
277     TS();
278     virtual ~TS();
279
280     enum
281     {
282         NUL=0,
283         SUMMARY_IDX=0,
284         SUMMARY=1 << SUMMARY_IDX,
285         LOG_IDX=1,
286         LOG=1 << LOG_IDX,
287         CSV_IDX=2,
288         CSV=1 << CSV_IDX,
289         CONSOLE_IDX=3,
290         CONSOLE=1 << CONSOLE_IDX,
291         MAX_IDX=4
292     };
293
294     static TS* ptr();
295     
296     // initialize test system before running the first test
297     virtual void init( const string& modulename );
298     
299     // low-level printing functions that are used by individual tests and by the system itself
300     virtual void printf( int streams, const char* fmt, ... );
301     virtual void vprintf( int streams, const char* fmt, va_list arglist );
302
303     // updates the context: current test, test case, rng state
304     virtual void update_context( BaseTest* test, int test_case_idx, bool update_ts_context );
305
306     const TestInfo* get_current_test_info() { return &current_test_info; }
307
308     // sets information about a failed test
309     virtual void set_failed_test_info( int fail_code );
310     
311     virtual void set_gtest_status();
312
313     // test error codes
314     enum
315     {
316         // everything is Ok
317         OK=0,
318
319         // generic error: stub value to be used
320         // temporarily if the error's cause is unknown
321         FAIL_GENERIC=-1,
322
323         // the test is missing some essential data to proceed further
324         FAIL_MISSING_TEST_DATA=-2,
325
326         // the tested function raised an error via cxcore error handler
327         FAIL_ERROR_IN_CALLED_FUNC=-3,
328
329         // an exception has been raised;
330         // for memory and arithmetic exception
331         // there are two specialized codes (see below...)
332         FAIL_EXCEPTION=-4,
333
334         // a memory exception
335         // (access violation, access to missed page, stack overflow etc.)
336         FAIL_MEMORY_EXCEPTION=-5,
337
338         // arithmetic exception (overflow, division by zero etc.)
339         FAIL_ARITHM_EXCEPTION=-6,
340
341         // the tested function corrupted memory (no exception have been raised)
342         FAIL_MEMORY_CORRUPTION_BEGIN=-7,
343         FAIL_MEMORY_CORRUPTION_END=-8,
344
345         // the tested function (or test ifself) do not deallocate some memory
346         FAIL_MEMORY_LEAK=-9,
347
348         // the tested function returned invalid object, e.g. matrix, containing NaNs,
349         // structure with NULL or out-of-range fields (while it should not)
350         FAIL_INVALID_OUTPUT=-10,
351
352         // the tested function returned valid object, but it does not match to
353         // the original (or produced by the test) object
354         FAIL_MISMATCH=-11,
355
356         // the tested function returned valid object (a single number or numerical array),
357         // but it differs too much from the original (or produced by the test) object
358         FAIL_BAD_ACCURACY=-12,
359
360         // the tested function hung. Sometimes, can be determined by unexpectedly long
361         // processing time (in this case there should be possibility to interrupt such a function
362         FAIL_HANG=-13,
363
364         // unexpected responce on passing bad arguments to the tested function
365         // (the function crashed, proceed succesfully (while it should not), or returned
366         // error code that is different from what is expected)
367         FAIL_BAD_ARG_CHECK=-14,
368
369         // the test data (in whole or for the particular test case) is invalid
370         FAIL_INVALID_TEST_DATA=-15,
371
372         // the test has been skipped because it is not in the selected subset of the tests to run,
373         // because it has been run already within the same run with the same parameters, or because
374         // of some other reason and this is not considered as an error.
375         // Normally TS::run() (or overrided method in the derived class) takes care of what
376         // needs to be run, so this code should not occur.
377         SKIPPED=1
378     };
379
380     // get file storage
381     CvFileStorage* get_file_storage();
382
383     // get RNG to generate random input data for a test
384     RNG& get_rng() { return rng; }
385
386     // returns the current error code
387     int get_err_code() { return current_test_info.code; }
388
389     // returns the test extensivity scale
390     double get_test_case_count_scale() { return params.test_case_count_scale; }
391
392     const string& get_data_path() const { return data_path; }
393
394     // returns textual description of failure code
395     static string str_from_code( int code );
396     
397 protected:
398
399     // these are allocated within a test to try keep them valid in case of stack corruption
400     RNG rng;
401
402     // information about the current test
403     TestInfo current_test_info;
404         
405     // the path to data files used by tests
406     string data_path;
407     
408     TSParams params;
409     std::string output_buf[MAX_IDX];
410 };
411
412
413 /*****************************************************************************************\
414 *            Subclass of BaseTest for testing functions that process dense arrays           *
415 \*****************************************************************************************/
416
417 class CV_EXPORTS ArrayTest : public BaseTest
418 {
419 public:
420     // constructor(s) and destructor
421     ArrayTest();
422     virtual ~ArrayTest();
423
424     virtual void clear();
425
426 protected:
427
428     virtual int read_params( CvFileStorage* fs );
429     virtual int prepare_test_case( int test_case_idx );
430     virtual int validate_test_results( int test_case_idx );
431
432     virtual void prepare_to_validation( int test_case_idx );
433     virtual void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
434     virtual void fill_array( int test_case_idx, int i, int j, Mat& arr );
435     virtual void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
436     virtual double get_success_error_level( int test_case_idx, int i, int j );
437
438     bool cvmat_allowed;
439     bool iplimage_allowed;
440     bool optional_mask;
441     bool element_wise_relative_error;
442
443     int min_log_array_size;
444     int max_log_array_size;
445
446     enum { INPUT, INPUT_OUTPUT, OUTPUT, REF_INPUT_OUTPUT, REF_OUTPUT, TEMP, MASK, MAX_ARR };
447
448     vector<vector<void*> > test_array;
449     vector<vector<Mat> > test_mat;
450     float buf[4];
451 };
452
453
454 class CV_EXPORTS BadArgTest : public BaseTest
455 {
456 public:
457     // constructor(s) and destructor
458     BadArgTest();
459     virtual ~BadArgTest();
460
461 protected:
462     virtual int run_test_case( int expected_code, const string& descr );
463     virtual void run_func(void) = 0;
464     int test_case_idx;
465     int progress;
466     double t, freq;   
467
468     template<class F>
469     int run_test_case( int expected_code, const string& _descr, F f)
470     {
471         double new_t = (double)cv::getTickCount(), dt;
472         if( test_case_idx < 0 )
473         {
474             test_case_idx = 0;
475             progress = 0;
476             dt = 0;
477         }
478         else
479         {
480             dt = (new_t - t)/(freq*1000);
481             t = new_t;
482         }
483         progress = update_progress(progress, test_case_idx, 0, dt);
484         
485         int errcount = 0;
486         bool thrown = false;
487         const char* descr = _descr.c_str() ? _descr.c_str() : "";
488
489         try
490         {
491             f();
492         }
493         catch(const cv::Exception& e)
494         {
495             thrown = true;
496             if( e.code != expected_code )
497             {
498                 ts->printf(TS::LOG, "%s (test case #%d): the error code %d is different from the expected %d\n",
499                     descr, test_case_idx, e.code, expected_code);
500                 errcount = 1;
501             }
502         }
503         catch(...)
504         {
505             thrown = true;
506             ts->printf(TS::LOG, "%s  (test case #%d): unknown exception was thrown (the function has likely crashed)\n",
507                        descr, test_case_idx);
508             errcount = 1;
509         }
510         if(!thrown)
511         {
512             ts->printf(TS::LOG, "%s  (test case #%d): no expected exception was thrown\n",
513                        descr, test_case_idx);
514             errcount = 1;
515         }
516         test_case_idx++;
517         
518         return errcount;
519     }
520 };
521     
522 struct CV_EXPORTS DefaultRngAuto
523 {
524     const uint64 old_state;
525     
526     DefaultRngAuto() : old_state(cv::theRNG().state) { cv::theRNG().state = (uint64)-1; }
527     ~DefaultRngAuto() { cv::theRNG().state = old_state; }
528     
529     DefaultRngAuto& operator=(const DefaultRngAuto&);
530 };
531     
532 }
533
534 // fills c with zeros
535 CV_EXPORTS void cvTsZero( CvMat* c, const CvMat* mask=0 );
536
537 // copies a to b (whole matrix or only the selected region)
538 CV_EXPORTS void cvTsCopy( const CvMat* a, CvMat* b, const CvMat* mask=0 );
539
540 // converts one array to another
541 CV_EXPORTS void  cvTsConvert( const CvMat* src, CvMat* dst );
542
543 CV_EXPORTS void cvTsGEMM( const CvMat* a, const CvMat* b, double alpha,
544                          const CvMat* c, double beta, CvMat* d, int flags );
545
546 #define CV_TEST_MAIN(resourcesubdir) \
547 int main(int argc, char **argv) \
548 { \
549     cvtest::TS::ptr()->init(resourcesubdir); \
550     ::testing::InitGoogleTest(&argc, argv); \
551     return RUN_ALL_TESTS(); \
552 }
553
554 #endif
555
556 #include "ts_perf.hpp"