ts.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. #ifndef OPENCV_TS_HPP
  2. #define OPENCV_TS_HPP
  3. #ifndef __OPENCV_TESTS
  4. #define __OPENCV_TESTS 1
  5. #endif
  6. #include "opencv2/opencv_modules.hpp"
  7. #include "opencv2/core.hpp"
  8. #include "opencv2/imgproc.hpp"
  9. #include "opencv2/imgcodecs.hpp"
  10. #include "opencv2/videoio.hpp"
  11. #include "opencv2/highgui.hpp"
  12. #include "opencv2/core/utility.hpp"
  13. #include "opencv2/core/utils/trace.hpp"
  14. #include "opencv2/core/hal/hal.hpp"
  15. #include <stdarg.h> // for va_list
  16. #include "cvconfig.h"
  17. #include <cmath>
  18. #include <vector>
  19. #include <list>
  20. #include <map>
  21. #include <queue>
  22. #include <string>
  23. #include <iostream>
  24. #include <fstream>
  25. #include <iomanip>
  26. #include <sstream>
  27. #include <cstdio>
  28. #include <iterator>
  29. #include <limits>
  30. #include <algorithm>
  31. #include <set>
  32. #ifndef OPENCV_32BIT_CONFIGURATION
  33. # if defined(INTPTR_MAX) && defined(INT32_MAX) && INTPTR_MAX == INT32_MAX
  34. # define OPENCV_32BIT_CONFIGURATION 1
  35. # elif defined(_WIN32) && !defined(_WIN64)
  36. # define OPENCV_32BIT_CONFIGURATION 1
  37. # endif
  38. #else
  39. # if OPENCV_32BIT_CONFIGURATION == 0
  40. # undef OPENCV_32BIT_CONFIGURATION
  41. # endif
  42. #endif
  43. // most part of OpenCV tests are fit into 200Mb limit, but some tests are not:
  44. // Note: due memory fragmentation real limits are usually lower on 20-25% (400Mb memory usage goes into mem_1Gb class)
  45. #define CV_TEST_TAG_MEMORY_512MB "mem_512mb" // used memory: 200..512Mb - enabled by default
  46. #define CV_TEST_TAG_MEMORY_1GB "mem_1gb" // used memory: 512Mb..1Gb - enabled by default
  47. #define CV_TEST_TAG_MEMORY_2GB "mem_2gb" // used memory: 1..2Gb - enabled by default on 64-bit configuration (32-bit - disabled)
  48. #define CV_TEST_TAG_MEMORY_6GB "mem_6gb" // used memory: 2..6Gb - disabled by default
  49. #define CV_TEST_TAG_MEMORY_14GB "mem_14gb" // used memory: 6..14Gb - disabled by default
  50. // Large / huge video streams or complex workloads
  51. #define CV_TEST_TAG_LONG "long" // 5+ seconds on modern desktop machine (single thread)
  52. #define CV_TEST_TAG_VERYLONG "verylong" // 20+ seconds on modern desktop machine (single thread)
  53. // Large / huge video streams or complex workloads for debug builds
  54. #define CV_TEST_TAG_DEBUG_LONG "debug_long" // 10+ seconds on modern desktop machine (single thread)
  55. #define CV_TEST_TAG_DEBUG_VERYLONG "debug_verylong" // 40+ seconds on modern desktop machine (single thread)
  56. // Lets skip processing of high resolution images via instrumentation tools (valgrind/coverage/sanitizers).
  57. // It is enough to run lower resolution (VGA: 640x480) tests.
  58. #define CV_TEST_TAG_SIZE_HD "size_hd" // 720p+, enabled
  59. #define CV_TEST_TAG_SIZE_FULLHD "size_fullhd" // 1080p+, enabled (disable these tests for valgrind/coverage run)
  60. #define CV_TEST_TAG_SIZE_4K "size_4k" // 2160p+, enabled (disable these tests for valgrind/coverage run)
  61. // Other misc test tags
  62. #define CV_TEST_TAG_TYPE_64F "type_64f" // CV_64F, enabled (disable these tests on low power embedded devices)
  63. // Kernel-based image processing
  64. #define CV_TEST_TAG_FILTER_SMALL "filter_small" // Filtering with kernels <= 3x3
  65. #define CV_TEST_TAG_FILTER_MEDIUM "filter_medium" // Filtering with kernels: 3x3 < kernel <= 5x5
  66. #define CV_TEST_TAG_FILTER_LARGE "filter_large" // Filtering with kernels: 5x5 < kernel <= 9x9
  67. #define CV_TEST_TAG_FILTER_HUGE "filter_huge" // Filtering with kernels: > 9x9
  68. // Other tests categories
  69. #define CV_TEST_TAG_OPENCL "opencl" // Tests with OpenCL
  70. #ifdef WINRT
  71. #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
  72. #endif
  73. #ifdef _MSC_VER
  74. #pragma warning( disable: 4503 ) // decorated name length exceeded, name was truncated
  75. #endif
  76. #define GTEST_DONT_DEFINE_FAIL 0
  77. #define GTEST_DONT_DEFINE_SUCCEED 0
  78. #define GTEST_DONT_DEFINE_ASSERT_EQ 0
  79. #define GTEST_DONT_DEFINE_ASSERT_NE 0
  80. #define GTEST_DONT_DEFINE_ASSERT_LE 0
  81. #define GTEST_DONT_DEFINE_ASSERT_LT 0
  82. #define GTEST_DONT_DEFINE_ASSERT_GE 0
  83. #define GTEST_DONT_DEFINE_ASSERT_GT 0
  84. #define GTEST_DONT_DEFINE_TEST 0
  85. #ifndef GTEST_LANG_CXX11
  86. #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && !(_MSVC_LANG < 201103))
  87. # define GTEST_LANG_CXX11 1
  88. # define GTEST_HAS_TR1_TUPLE 0
  89. # define GTEST_HAS_COMBINE 1
  90. # endif
  91. #endif
  92. #if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
  93. //#pragma GCC diagnostic push
  94. #pragma GCC diagnostic ignored "-Wsuggest-override"
  95. #endif
  96. #if defined(__OPENCV_BUILD) && defined(__clang__) && ((__clang_major__*100 + __clang_minor__) >= 1301)
  97. #pragma clang diagnostic push
  98. #pragma clang diagnostic ignored "-Wdeprecated-copy"
  99. #pragma clang diagnostic ignored "-Winconsistent-missing-override"
  100. #endif
  101. #include "opencv2/ts/ts_gtest.h"
  102. #if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
  103. //#pragma GCC diagnostic pop
  104. #endif
  105. #if defined(__OPENCV_BUILD) && defined(__clang__) && ((__clang_major__*100 + __clang_minor__) >= 1301)
  106. #pragma clang diagnostic pop
  107. #endif
  108. #include "opencv2/ts/ts_ext.hpp"
  109. #ifndef GTEST_USES_SIMPLE_RE
  110. # define GTEST_USES_SIMPLE_RE 0
  111. #endif
  112. #ifndef GTEST_USES_POSIX_RE
  113. # define GTEST_USES_POSIX_RE 0
  114. #endif
  115. #define PARAM_TEST_CASE(name, ...) struct name : testing::TestWithParam< testing::tuple< __VA_ARGS__ > >
  116. #define GET_PARAM(k) testing::get< k >(GetParam())
  117. namespace cvtest
  118. {
  119. using std::vector;
  120. using std::map;
  121. using std::string;
  122. using std::stringstream;
  123. using std::cout;
  124. using std::cerr;
  125. using std::endl;
  126. using std::min;
  127. using std::max;
  128. using std::numeric_limits;
  129. using std::pair;
  130. using std::make_pair;
  131. using testing::TestWithParam;
  132. using testing::Values;
  133. using testing::ValuesIn;
  134. using testing::Combine;
  135. using cv::Mat;
  136. using cv::Mat_;
  137. using cv::UMat;
  138. using cv::InputArray;
  139. using cv::OutputArray;
  140. using cv::noArray;
  141. using cv::Range;
  142. using cv::Point;
  143. using cv::Rect;
  144. using cv::Size;
  145. using cv::Scalar;
  146. using cv::RNG;
  147. // Tuple stuff from Google Tests
  148. using testing::get;
  149. using testing::make_tuple;
  150. using testing::tuple;
  151. using testing::tuple_size;
  152. using testing::tuple_element;
  153. namespace details {
  154. class SkipTestExceptionBase: public cv::Exception
  155. {
  156. public:
  157. SkipTestExceptionBase(bool handlingTags);
  158. SkipTestExceptionBase(const cv::String& message, bool handlingTags);
  159. };
  160. }
  161. class SkipTestException: public details::SkipTestExceptionBase
  162. {
  163. public:
  164. int dummy; // workaround for MacOSX Xcode 7.3 bug (don't make class "empty")
  165. SkipTestException() : details::SkipTestExceptionBase(false), dummy(0) {}
  166. SkipTestException(const cv::String& message) : details::SkipTestExceptionBase(message, false), dummy(0) { }
  167. };
  168. /** Apply tag to the current test
  169. Automatically apply corresponding additional tags (for example, 4K => FHD => HD => VGA).
  170. If tag is in skip list, then SkipTestException is thrown
  171. */
  172. void applyTestTag(const std::string& tag);
  173. /** Run postponed checks of applied test tags
  174. If tag is in skip list, then SkipTestException is thrown
  175. */
  176. void checkTestTags();
  177. void applyTestTag_(const std::string& tag);
  178. static inline void applyTestTag(const std::string& tag1, const std::string& tag2)
  179. { applyTestTag_(tag1); applyTestTag_(tag2); checkTestTags(); }
  180. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3)
  181. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); checkTestTags(); }
  182. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4)
  183. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); applyTestTag_(tag4); checkTestTags(); }
  184. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4, const std::string& tag5)
  185. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); applyTestTag_(tag4); applyTestTag_(tag5); checkTestTags(); }
  186. /** Append global skip test tags
  187. */
  188. void registerGlobalSkipTag(const std::string& skipTag);
  189. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2)
  190. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); }
  191. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3)
  192. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); }
  193. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4)
  194. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4); }
  195. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  196. const std::string& tag5)
  197. {
  198. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  199. registerGlobalSkipTag(tag5);
  200. }
  201. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  202. const std::string& tag5, const std::string& tag6)
  203. {
  204. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  205. registerGlobalSkipTag(tag5); registerGlobalSkipTag(tag6);
  206. }
  207. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  208. const std::string& tag5, const std::string& tag6, const std::string& tag7)
  209. {
  210. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  211. registerGlobalSkipTag(tag5); registerGlobalSkipTag(tag6); registerGlobalSkipTag(tag7);
  212. }
  213. class TS;
  214. int64 readSeed(const char* str);
  215. void randUni( RNG& rng, Mat& a, const Scalar& param1, const Scalar& param2 );
  216. inline unsigned randInt( RNG& rng )
  217. {
  218. return (unsigned)rng;
  219. }
  220. inline double randReal( RNG& rng )
  221. {
  222. return (double)rng;
  223. }
  224. const char* getTypeName( int type );
  225. int typeByName( const char* type_name );
  226. string vec2str(const string& sep, const int* v, size_t nelems);
  227. inline int clipInt( int val, int min_val, int max_val )
  228. {
  229. if( val < min_val )
  230. val = min_val;
  231. if( val > max_val )
  232. val = max_val;
  233. return val;
  234. }
  235. double getMinVal(int depth);
  236. double getMaxVal(int depth);
  237. Size randomSize(RNG& rng, double maxSizeLog);
  238. void randomSize(RNG& rng, int minDims, int maxDims, double maxSizeLog, vector<int>& sz);
  239. int randomType(RNG& rng, cv::_OutputArray::DepthMask typeMask, int minChannels, int maxChannels);
  240. Mat randomMat(RNG& rng, Size size, int type, double minVal, double maxVal, bool useRoi);
  241. Mat randomMat(RNG& rng, const vector<int>& size, int type, double minVal, double maxVal, bool useRoi);
  242. void add(const Mat& a, double alpha, const Mat& b, double beta,
  243. Scalar gamma, Mat& c, int ctype, bool calcAbs=false);
  244. void multiply(const Mat& a, const Mat& b, Mat& c, double alpha=1, int ctype=-1);
  245. void divide(const Mat& a, const Mat& b, Mat& c, double alpha=1, int ctype=-1);
  246. void convert(const Mat& src, cv::OutputArray dst, int dtype, double alpha=1, double beta=0);
  247. void copy(const Mat& src, Mat& dst, const Mat& mask=Mat(), bool invertMask=false);
  248. void set(Mat& dst, const Scalar& gamma, const Mat& mask=Mat());
  249. // working with multi-channel arrays
  250. void extract( const Mat& a, Mat& plane, int coi );
  251. void insert( const Mat& plane, Mat& a, int coi );
  252. // checks that the array does not have NaNs and/or Infs and all the elements are
  253. // within [min_val,max_val). idx is the index of the first "bad" element.
  254. int check( const Mat& data, double min_val, double max_val, vector<int>* idx );
  255. // modifies values that are close to zero
  256. void patchZeros( Mat& mat, double level );
  257. void transpose(const Mat& src, Mat& dst);
  258. void erode(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
  259. int borderType=0, const Scalar& borderValue=Scalar());
  260. void dilate(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
  261. int borderType=0, const Scalar& borderValue=Scalar());
  262. void filter2D(const Mat& src, Mat& dst, int ddepth, const Mat& kernel,
  263. Point anchor, double delta, int borderType,
  264. const Scalar& borderValue=Scalar());
  265. void copyMakeBorder(const Mat& src, Mat& dst, int top, int bottom, int left, int right,
  266. int borderType, const Scalar& borderValue=Scalar());
  267. Mat calcSobelKernel2D( int dx, int dy, int apertureSize, int origin=0 );
  268. Mat calcLaplaceKernel2D( int aperture_size );
  269. void initUndistortMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type );
  270. void initInverseRectificationMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type );
  271. void minMaxLoc(const Mat& src, double* minval, double* maxval,
  272. vector<int>* minloc, vector<int>* maxloc, const Mat& mask=Mat());
  273. double norm(InputArray src, int normType, InputArray mask=noArray());
  274. double norm(InputArray src1, InputArray src2, int normType, InputArray mask=noArray());
  275. Scalar mean(const Mat& src, const Mat& mask=Mat());
  276. double PSNR(InputArray src1, InputArray src2);
  277. bool cmpUlps(const Mat& data, const Mat& refdata, int expMaxDiff, double* realMaxDiff, vector<int>* idx);
  278. // compares two arrays. max_diff is the maximum actual difference,
  279. // success_err_level is maximum allowed difference, idx is the index of the first
  280. // element for which difference is >success_err_level
  281. // (or index of element with the maximum difference)
  282. int cmpEps( const Mat& data, const Mat& refdata, double* max_diff,
  283. double success_err_level, vector<int>* idx,
  284. bool element_wise_relative_error );
  285. // a wrapper for the previous function. in case of error prints the message to log file.
  286. int cmpEps2( TS* ts, const Mat& data, const Mat& refdata, double success_err_level,
  287. bool element_wise_relative_error, const char* desc );
  288. int cmpEps2_64f( TS* ts, const double* val, const double* refval, int len,
  289. double eps, const char* param_name );
  290. void logicOp(const Mat& src1, const Mat& src2, Mat& dst, char c);
  291. void logicOp(const Mat& src, const Scalar& s, Mat& dst, char c);
  292. void min(const Mat& src1, const Mat& src2, Mat& dst);
  293. void min(const Mat& src, double s, Mat& dst);
  294. void max(const Mat& src1, const Mat& src2, Mat& dst);
  295. void max(const Mat& src, double s, Mat& dst);
  296. void compare(const Mat& src1, const Mat& src2, Mat& dst, int cmpop);
  297. void compare(const Mat& src, double s, Mat& dst, int cmpop);
  298. void gemm(const Mat& src1, const Mat& src2, double alpha,
  299. const Mat& src3, double beta, Mat& dst, int flags);
  300. void transform( const Mat& src, Mat& dst, const Mat& transmat, const Mat& shift );
  301. double crossCorr(const Mat& src1, const Mat& src2);
  302. void threshold( const Mat& src, Mat& dst, double thresh, double maxval, int thresh_type );
  303. void minMaxIdx( InputArray _img, double* minVal, double* maxVal,
  304. Point* minLoc, Point* maxLoc, InputArray _mask );
  305. struct MatInfo
  306. {
  307. MatInfo(const Mat& _m) : m(&_m) {}
  308. const Mat* m;
  309. };
  310. std::ostream& operator << (std::ostream& out, const MatInfo& m);
  311. struct MatComparator
  312. {
  313. public:
  314. MatComparator(double maxdiff, int context);
  315. ::testing::AssertionResult operator()(const char* expr1, const char* expr2,
  316. const Mat& m1, const Mat& m2);
  317. double maxdiff;
  318. double realmaxdiff;
  319. vector<int> loc0;
  320. int context;
  321. };
  322. class BaseTest;
  323. class TS;
  324. class BaseTest
  325. {
  326. public:
  327. // constructor(s) and destructor
  328. BaseTest();
  329. virtual ~BaseTest();
  330. // the main procedure of the test
  331. virtual void run( int start_from );
  332. // the wrapper for run that cares of exceptions
  333. virtual void safe_run( int start_from=0 );
  334. const string& get_name() const { return name; }
  335. // returns true if and only if the different test cases do not depend on each other
  336. // (so that test system could get right to a problematic test case)
  337. virtual bool can_do_fast_forward();
  338. // deallocates all the memory.
  339. // called by init() (before initialization) and by the destructor
  340. virtual void clear();
  341. protected:
  342. int test_case_count; // the total number of test cases
  343. // read test params
  344. virtual int read_params( const cv::FileStorage& fs );
  345. // returns the number of tests or -1 if it is unknown a-priori
  346. virtual int get_test_case_count();
  347. // prepares data for the next test case. rng seed is updated by the function
  348. virtual int prepare_test_case( int test_case_idx );
  349. // checks if the test output is valid and accurate
  350. virtual int validate_test_results( int test_case_idx );
  351. // calls the tested function. the method is called from run_test_case()
  352. virtual void run_func(); // runs tested func(s)
  353. // updates progress bar
  354. virtual int update_progress( int progress, int test_case_idx, int count, double dt );
  355. // dump test case input parameters
  356. virtual void dump_test_case(int test_case_idx, std::ostream* out);
  357. // finds test parameter
  358. cv::FileNode find_param( const cv::FileStorage& fs, const char* param_name );
  359. // name of the test (it is possible to locate a test by its name)
  360. string name;
  361. // pointer to the system that includes the test
  362. TS* ts;
  363. };
  364. /*****************************************************************************************\
  365. * Information about a failed test *
  366. \*****************************************************************************************/
  367. struct TestInfo
  368. {
  369. TestInfo();
  370. // pointer to the test
  371. BaseTest* test;
  372. // failure code (TS::FAIL_*)
  373. int code;
  374. // seed value right before the data for the failed test case is prepared.
  375. uint64 rng_seed;
  376. // seed value right before running the test
  377. uint64 rng_seed0;
  378. // index of test case, can be then passed to BaseTest::proceed_to_test_case()
  379. int test_case_idx;
  380. };
  381. /*****************************************************************************************\
  382. * Base Class for test system *
  383. \*****************************************************************************************/
  384. // common parameters:
  385. struct TSParams
  386. {
  387. TSParams();
  388. // RNG seed, passed to and updated by every test executed.
  389. uint64 rng_seed;
  390. // whether to use IPP, MKL etc. or not
  391. bool use_optimized;
  392. // extensivity of the tests, scale factor for test_case_count
  393. double test_case_count_scale;
  394. };
  395. class TS
  396. {
  397. TS();
  398. virtual ~TS();
  399. public:
  400. enum
  401. {
  402. NUL=0,
  403. SUMMARY_IDX=0,
  404. SUMMARY=1 << SUMMARY_IDX,
  405. LOG_IDX=1,
  406. LOG=1 << LOG_IDX,
  407. CSV_IDX=2,
  408. CSV=1 << CSV_IDX,
  409. CONSOLE_IDX=3,
  410. CONSOLE=1 << CONSOLE_IDX,
  411. MAX_IDX=4
  412. };
  413. static TS* ptr();
  414. // initialize test system before running the first test
  415. virtual void init( const string& modulename );
  416. // low-level printing functions that are used by individual tests and by the system itself
  417. virtual void printf( int streams, const char* fmt, ... );
  418. virtual void vprintf( int streams, const char* fmt, va_list arglist );
  419. // updates the context: current test, test case, rng state
  420. virtual void update_context( BaseTest* test, int test_case_idx, bool update_ts_context );
  421. const TestInfo* get_current_test_info() { return &current_test_info; }
  422. // sets information about a failed test
  423. virtual void set_failed_test_info( int fail_code );
  424. virtual void set_gtest_status();
  425. // test error codes
  426. enum FailureCode
  427. {
  428. // everything is Ok
  429. OK=0,
  430. // generic error: stub value to be used
  431. // temporarily if the error's cause is unknown
  432. FAIL_GENERIC=-1,
  433. // the test is missing some essential data to proceed further
  434. FAIL_MISSING_TEST_DATA=-2,
  435. // the tested function raised an error via cxcore error handler
  436. FAIL_ERROR_IN_CALLED_FUNC=-3,
  437. // an exception has been raised;
  438. // for memory and arithmetic exception
  439. // there are two specialized codes (see below...)
  440. FAIL_EXCEPTION=-4,
  441. // a memory exception
  442. // (access violation, access to missed page, stack overflow etc.)
  443. FAIL_MEMORY_EXCEPTION=-5,
  444. // arithmetic exception (overflow, division by zero etc.)
  445. FAIL_ARITHM_EXCEPTION=-6,
  446. // the tested function corrupted memory (no exception have been raised)
  447. FAIL_MEMORY_CORRUPTION_BEGIN=-7,
  448. FAIL_MEMORY_CORRUPTION_END=-8,
  449. // the tested function (or test itself) do not deallocate some memory
  450. FAIL_MEMORY_LEAK=-9,
  451. // the tested function returned invalid object, e.g. matrix, containing NaNs,
  452. // structure with NULL or out-of-range fields (while it should not)
  453. FAIL_INVALID_OUTPUT=-10,
  454. // the tested function returned valid object, but it does not match
  455. // the original (or produced by the test) object
  456. FAIL_MISMATCH=-11,
  457. // the tested function returned valid object (a single number or numerical array),
  458. // but it differs too much from the original (or produced by the test) object
  459. FAIL_BAD_ACCURACY=-12,
  460. // the tested function hung. Sometimes, it can be determined by unexpectedly long
  461. // processing time (in this case there should be possibility to interrupt such a function
  462. FAIL_HANG=-13,
  463. // unexpected response on passing bad arguments to the tested function
  464. // (the function crashed, proceed successfully (while it should not), or returned
  465. // error code that is different from what is expected)
  466. FAIL_BAD_ARG_CHECK=-14,
  467. // the test data (in whole or for the particular test case) is invalid
  468. FAIL_INVALID_TEST_DATA=-15,
  469. // the test has been skipped because it is not in the selected subset of the tests to run,
  470. // because it has been run already within the same run with the same parameters, or because
  471. // of some other reason and this is not considered as an error.
  472. // Normally TS::run() (or overridden method in the derived class) takes care of what
  473. // needs to be run, so this code should not occur.
  474. SKIPPED=1
  475. };
  476. // get RNG to generate random input data for a test
  477. RNG& get_rng() { return cv::theRNG(); }
  478. // returns the current error code
  479. TS::FailureCode get_err_code() { return TS::FailureCode(current_test_info.code); }
  480. // returns the test extensivity scale
  481. double get_test_case_count_scale() { return params.test_case_count_scale; }
  482. const string& get_data_path() const { return data_path; }
  483. // returns textual description of failure code
  484. static string str_from_code( const TS::FailureCode code );
  485. std::vector<std::string> data_search_path;
  486. std::vector<std::string> data_search_subdir;
  487. protected:
  488. // these are allocated within a test to try to keep them valid in case of stack corruption
  489. // information about the current test
  490. TestInfo current_test_info;
  491. // the path to data files used by tests
  492. string data_path;
  493. TSParams params;
  494. std::string output_buf[MAX_IDX];
  495. };
  496. /*****************************************************************************************\
  497. * Subclass of BaseTest for testing functions that process dense arrays *
  498. \*****************************************************************************************/
  499. class ArrayTest : public BaseTest
  500. {
  501. public:
  502. // constructor(s) and destructor
  503. ArrayTest();
  504. virtual ~ArrayTest();
  505. virtual void clear() CV_OVERRIDE;
  506. protected:
  507. virtual int read_params( const cv::FileStorage& fs ) CV_OVERRIDE;
  508. virtual int prepare_test_case( int test_case_idx ) CV_OVERRIDE;
  509. virtual int validate_test_results( int test_case_idx ) CV_OVERRIDE;
  510. virtual void prepare_to_validation( int test_case_idx );
  511. virtual void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  512. virtual void fill_array( int test_case_idx, int i, int j, Mat& arr );
  513. virtual void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
  514. virtual double get_success_error_level( int test_case_idx, int i, int j );
  515. bool cvmat_allowed;
  516. bool iplimage_allowed;
  517. bool optional_mask;
  518. bool element_wise_relative_error;
  519. int min_log_array_size;
  520. int max_log_array_size;
  521. enum { INPUT, INPUT_OUTPUT, OUTPUT, REF_INPUT_OUTPUT, REF_OUTPUT, TEMP, MASK, MAX_ARR };
  522. vector<vector<void*> > test_array;
  523. vector<vector<Mat> > test_mat;
  524. float buf[4];
  525. };
  526. class BadArgTest : public BaseTest
  527. {
  528. public:
  529. // constructor(s) and destructor
  530. BadArgTest();
  531. virtual ~BadArgTest();
  532. protected:
  533. virtual int run_test_case( int expected_code, const string& descr );
  534. virtual void run_func(void) CV_OVERRIDE = 0;
  535. int test_case_idx;
  536. template<class F>
  537. int run_test_case( int expected_code, const string& _descr, F f)
  538. {
  539. int errcount = 0;
  540. bool thrown = false;
  541. const char* descr = _descr.c_str() ? _descr.c_str() : "";
  542. try
  543. {
  544. f();
  545. }
  546. catch(const cv::Exception& e)
  547. {
  548. thrown = true;
  549. if( e.code != expected_code && e.code != cv::Error::StsAssert && e.code != cv::Error::StsError )
  550. {
  551. ts->printf(TS::LOG, "%s (test case #%d): the error code %d is different from the expected %d\n",
  552. descr, test_case_idx, e.code, expected_code);
  553. errcount = 1;
  554. }
  555. }
  556. catch(...)
  557. {
  558. thrown = true;
  559. ts->printf(TS::LOG, "%s (test case #%d): unknown exception was thrown (the function has likely crashed)\n",
  560. descr, test_case_idx);
  561. errcount = 1;
  562. }
  563. if(!thrown)
  564. {
  565. ts->printf(TS::LOG, "%s (test case #%d): no expected exception was thrown\n",
  566. descr, test_case_idx);
  567. errcount = 1;
  568. }
  569. test_case_idx++;
  570. return errcount;
  571. }
  572. };
  573. extern uint64 param_seed;
  574. struct DefaultRngAuto
  575. {
  576. const uint64 old_state;
  577. DefaultRngAuto() : old_state(cv::theRNG().state) { cv::theRNG().state = cvtest::param_seed; }
  578. ~DefaultRngAuto() { cv::theRNG().state = old_state; }
  579. DefaultRngAuto& operator=(const DefaultRngAuto&);
  580. };
  581. // test images generation functions
  582. void fillGradient(Mat& img, int delta = 5);
  583. void smoothBorder(Mat& img, const Scalar& color, int delta = 3);
  584. // Utility functions
  585. void addDataSearchPath(const std::string& path);
  586. void addDataSearchEnv(const std::string& env_name);
  587. void addDataSearchSubDirectory(const std::string& subdir);
  588. /*! @brief Try to find requested data file
  589. Search directories:
  590. 0. TS::data_search_path (search sub-directories are not used)
  591. 1. OPENCV_TEST_DATA_PATH environment variable
  592. 2. One of these:
  593. a. OpenCV testdata based on build location: "./" + "share/OpenCV/testdata"
  594. b. OpenCV testdata at install location: CMAKE_INSTALL_PREFIX + "share/OpenCV/testdata"
  595. Search sub-directories:
  596. - addDataSearchSubDirectory()
  597. - modulename from TS::init()
  598. */
  599. std::string findDataFile(const std::string& relative_path, bool required = true);
  600. /*! @brief Try to find requested data directory
  601. @sa findDataFile
  602. */
  603. std::string findDataDirectory(const std::string& relative_path, bool required = true);
  604. // Test definitions
  605. class SystemInfoCollector : public testing::EmptyTestEventListener
  606. {
  607. private:
  608. virtual void OnTestProgramStart(const testing::UnitTest&);
  609. };
  610. #ifndef __CV_TEST_EXEC_ARGS
  611. #if defined(_MSC_VER) && (_MSC_VER <= 1400)
  612. #define __CV_TEST_EXEC_ARGS(...) \
  613. while (++argc >= (--argc,-1)) {__VA_ARGS__; break;} /*this ugly construction is needed for VS 2005*/
  614. #else
  615. #define __CV_TEST_EXEC_ARGS(...) \
  616. __VA_ARGS__;
  617. #endif
  618. #endif
  619. void parseCustomOptions(int argc, char **argv);
  620. #define CV_TEST_INIT0_NOOP (void)0
  621. #define CV_TEST_MAIN(resourcesubdir, ...) CV_TEST_MAIN_EX(resourcesubdir, NOOP, __VA_ARGS__)
  622. #define CV_TEST_MAIN_EX(resourcesubdir, INIT0, ...) \
  623. int main(int argc, char **argv) \
  624. { \
  625. CV_TRACE_FUNCTION(); \
  626. { CV_TRACE_REGION("INIT"); \
  627. using namespace cvtest; using namespace opencv_test; \
  628. TS* ts = TS::ptr(); \
  629. ts->init(resourcesubdir); \
  630. __CV_TEST_EXEC_ARGS(CV_TEST_INIT0_ ## INIT0) \
  631. ::testing::InitGoogleTest(&argc, argv); \
  632. ::testing::UnitTest::GetInstance()->listeners().Append(new SystemInfoCollector); \
  633. __CV_TEST_EXEC_ARGS(__VA_ARGS__) \
  634. parseCustomOptions(argc, argv); \
  635. } \
  636. return RUN_ALL_TESTS(); \
  637. }
  638. // This usually only makes sense in perf tests with several implementations,
  639. // some of which are not available.
  640. #define CV_TEST_FAIL_NO_IMPL() do { \
  641. ::testing::Test::RecordProperty("custom_status", "noimpl"); \
  642. FAIL() << "No equivalent implementation."; \
  643. } while (0)
  644. } //namespace cvtest
  645. #include "opencv2/ts/ts_perf.hpp"
  646. namespace cvtest {
  647. using perf::MatDepth;
  648. using perf::MatType;
  649. }
  650. #ifdef WINRT
  651. #ifndef __FSTREAM_EMULATED__
  652. #define __FSTREAM_EMULATED__
  653. #include <stdlib.h>
  654. #include <fstream>
  655. #include <sstream>
  656. #undef ifstream
  657. #undef ofstream
  658. #define ifstream ifstream_emulated
  659. #define ofstream ofstream_emulated
  660. namespace std {
  661. class ifstream : public stringstream
  662. {
  663. FILE* f;
  664. public:
  665. ifstream(const char* filename, ios_base::openmode mode = ios_base::in)
  666. : f(NULL)
  667. {
  668. string modeStr("r");
  669. printf("Open file (read): %s\n", filename);
  670. if (mode & ios_base::binary)
  671. modeStr += "b";
  672. f = fopen(filename, modeStr.c_str());
  673. if (f == NULL)
  674. {
  675. printf("Can't open file: %s\n", filename);
  676. return;
  677. }
  678. fseek(f, 0, SEEK_END);
  679. size_t sz = ftell(f);
  680. if (sz > 0)
  681. {
  682. char* buf = (char*) malloc(sz);
  683. fseek(f, 0, SEEK_SET);
  684. if (fread(buf, 1, sz, f) == sz)
  685. {
  686. this->str(std::string(buf, sz));
  687. }
  688. free(buf);
  689. }
  690. }
  691. ~ifstream() { close(); }
  692. bool is_open() const { return f != NULL; }
  693. void close()
  694. {
  695. if (f)
  696. fclose(f);
  697. f = NULL;
  698. this->str("");
  699. }
  700. };
  701. class ofstream : public stringstream
  702. {
  703. FILE* f;
  704. public:
  705. ofstream(const char* filename, ios_base::openmode mode = ios_base::out)
  706. : f(NULL)
  707. {
  708. open(filename, mode);
  709. }
  710. ~ofstream() { close(); }
  711. void open(const char* filename, ios_base::openmode mode = ios_base::out)
  712. {
  713. string modeStr("w+");
  714. if (mode & ios_base::trunc)
  715. modeStr = "w";
  716. if (mode & ios_base::binary)
  717. modeStr += "b";
  718. f = fopen(filename, modeStr.c_str());
  719. printf("Open file (write): %s\n", filename);
  720. if (f == NULL)
  721. {
  722. printf("Can't open file (write): %s\n", filename);
  723. return;
  724. }
  725. }
  726. bool is_open() const { return f != NULL; }
  727. void close()
  728. {
  729. if (f)
  730. {
  731. fwrite(reinterpret_cast<const char *>(this->str().c_str()), this->str().size(), 1, f);
  732. fclose(f);
  733. }
  734. f = NULL;
  735. this->str("");
  736. }
  737. };
  738. } // namespace std
  739. #endif // __FSTREAM_EMULATED__
  740. #endif // WINRT
  741. namespace opencv_test {
  742. using namespace cvtest;
  743. using namespace cv;
  744. #define CVTEST_GUARD_SYMBOL(name) \
  745. class required_namespace_specificatin_here_for_symbol_ ## name {}; \
  746. using name = required_namespace_specificatin_here_for_symbol_ ## name;
  747. CVTEST_GUARD_SYMBOL(norm)
  748. CVTEST_GUARD_SYMBOL(add)
  749. CVTEST_GUARD_SYMBOL(multiply)
  750. CVTEST_GUARD_SYMBOL(divide)
  751. CVTEST_GUARD_SYMBOL(transpose)
  752. CVTEST_GUARD_SYMBOL(copyMakeBorder)
  753. CVTEST_GUARD_SYMBOL(filter2D)
  754. CVTEST_GUARD_SYMBOL(compare)
  755. CVTEST_GUARD_SYMBOL(minMaxIdx)
  756. CVTEST_GUARD_SYMBOL(threshold)
  757. extern bool required_opencv_test_namespace; // compilation check for non-refactored tests
  758. }
  759. #endif // OPENCV_TS_HPP