OpenCV 2.4.8 components for OpenCVgrabber.
[mmanager-3rdparty.git] / OpenCV2.4.8 / build / include / opencv2 / ts / ts_perf.hpp
1 #ifndef __OPENCV_TS_PERF_HPP__
2 #define __OPENCV_TS_PERF_HPP__
3
4 #include "opencv2/core/core.hpp"
5 #include "opencv2/imgproc/imgproc.hpp"
6 #include "opencv2/features2d/features2d.hpp"
7 #include "ts_gtest.h"
8
9 #ifdef HAVE_TBB
10 #include "tbb/task_scheduler_init.h"
11 #endif
12
13 #if !(defined(LOGD) || defined(LOGI) || defined(LOGW) || defined(LOGE))
14 # if defined(ANDROID) && defined(USE_ANDROID_LOGGING)
15 #  include <android/log.h>
16
17 #  define PERF_TESTS_LOG_TAG "OpenCV_perf"
18 #  define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, PERF_TESTS_LOG_TAG, __VA_ARGS__))
19 #  define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, PERF_TESTS_LOG_TAG, __VA_ARGS__))
20 #  define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, PERF_TESTS_LOG_TAG, __VA_ARGS__))
21 #  define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, PERF_TESTS_LOG_TAG, __VA_ARGS__))
22 # else
23 #  define LOGD(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
24 #  define LOGI(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
25 #  define LOGW(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
26 #  define LOGE(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
27 # endif
28 #endif
29
30 // declare major namespaces to avoid errors on unknown namespace
31 namespace cv { namespace gpu {} namespace ocl {} }
32
33 namespace perf
34 {
35 class TestBase;
36
37 /*****************************************************************************************\
38 *                Predefined typical frame sizes and typical test parameters               *
39 \*****************************************************************************************/
40 const cv::Size szQVGA = cv::Size(320, 240);
41 const cv::Size szVGA = cv::Size(640, 480);
42 const cv::Size szSVGA = cv::Size(800, 600);
43 const cv::Size szXGA = cv::Size(1024, 768);
44 const cv::Size szSXGA = cv::Size(1280, 1024);
45 const cv::Size szWQHD = cv::Size(2560, 1440);
46
47 const cv::Size sznHD = cv::Size(640, 360);
48 const cv::Size szqHD = cv::Size(960, 540);
49 const cv::Size sz240p = szQVGA;
50 const cv::Size sz720p = cv::Size(1280, 720);
51 const cv::Size sz1080p = cv::Size(1920, 1080);
52 const cv::Size sz1440p = szWQHD;
53 const cv::Size sz2160p = cv::Size(3840, 2160);//UHDTV1 4K
54 const cv::Size sz4320p = cv::Size(7680, 4320);//UHDTV2 8K
55
56 const cv::Size sz3MP = cv::Size(2048, 1536);
57 const cv::Size sz5MP = cv::Size(2592, 1944);
58 const cv::Size sz2K = cv::Size(2048, 2048);
59
60 const cv::Size szODD = cv::Size(127, 61);
61
62 const cv::Size szSmall24 = cv::Size(24, 24);
63 const cv::Size szSmall32 = cv::Size(32, 32);
64 const cv::Size szSmall64 = cv::Size(64, 64);
65 const cv::Size szSmall128 = cv::Size(128, 128);
66
67 #define SZ_ALL_VGA ::testing::Values(::perf::szQVGA, ::perf::szVGA, ::perf::szSVGA)
68 #define SZ_ALL_GA  ::testing::Values(::perf::szQVGA, ::perf::szVGA, ::perf::szSVGA, ::perf::szXGA, ::perf::szSXGA)
69 #define SZ_ALL_HD  ::testing::Values(::perf::sznHD, ::perf::szqHD, ::perf::sz720p, ::perf::sz1080p)
70 #define SZ_ALL_SMALL ::testing::Values(::perf::szSmall24, ::perf::szSmall32, ::perf::szSmall64, ::perf::szSmall128)
71 #define SZ_ALL  ::testing::Values(::perf::szQVGA, ::perf::szVGA, ::perf::szSVGA, ::perf::szXGA, ::perf::szSXGA, ::perf::sznHD, ::perf::szqHD, ::perf::sz720p, ::perf::sz1080p)
72 #define SZ_TYPICAL  ::testing::Values(::perf::szVGA, ::perf::szqHD, ::perf::sz720p, ::perf::szODD)
73
74
75 #define TYPICAL_MAT_SIZES ::perf::szVGA, ::perf::sz720p, ::perf::sz1080p, ::perf::szODD
76 #define TYPICAL_MAT_TYPES CV_8UC1, CV_8UC4, CV_32FC1
77 #define TYPICAL_MATS testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), testing::Values( TYPICAL_MAT_TYPES ) )
78 #define TYPICAL_MATS_C1 testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), testing::Values( CV_8UC1, CV_32FC1 ) )
79 #define TYPICAL_MATS_C4 testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), testing::Values( CV_8UC4 ) )
80
81
82 /*****************************************************************************************\
83 *                MatType - printable wrapper over integer 'type' of Mat                   *
84 \*****************************************************************************************/
85 class MatType
86 {
87 public:
88     MatType(int val=0) : _type(val) {}
89     operator int() const {return _type;}
90
91 private:
92     int _type;
93 };
94
95 /*****************************************************************************************\
96 *     CV_ENUM and CV_FLAGS - macro to create printable wrappers for defines and enums     *
97 \*****************************************************************************************/
98
99 #define CV_ENUM(class_name, ...)                                                        \
100     namespace {                                                                         \
101     struct class_name {                                                                 \
102         class_name(int val = 0) : val_(val) {}                                          \
103         operator int() const { return val_; }                                           \
104         void PrintTo(std::ostream* os) const {                                          \
105             using namespace cv;using namespace cv::gpu; using namespace cv::ocl;        \
106             const int vals[] = { __VA_ARGS__ };                                         \
107             const char* svals = #__VA_ARGS__;                                           \
108             for(int i = 0, pos = 0; i < (int)(sizeof(vals)/sizeof(int)); ++i) {         \
109                 while(isspace(svals[pos]) || svals[pos] == ',') ++pos;                  \
110                 int start = pos;                                                        \
111                 while(!(isspace(svals[pos]) || svals[pos] == ',' || svals[pos] == 0))   \
112                     ++pos;                                                              \
113                 if (val_ == vals[i]) {                                                  \
114                     *os << std::string(svals + start, svals + pos);                     \
115                     return;                                                             \
116                 }                                                                       \
117             }                                                                           \
118             *os << "UNKNOWN";                                                           \
119         }                                                                               \
120         static ::testing::internal::ParamGenerator<class_name> all() {                  \
121             using namespace cv;using namespace cv::gpu; using namespace cv::ocl;        \
122             static class_name vals[] = { __VA_ARGS__ };                                 \
123             return ::testing::ValuesIn(vals);                                           \
124         }                                                                               \
125     private: int val_;                                                                  \
126     };                                                                                  \
127     inline void PrintTo(const class_name& t, std::ostream* os) { t.PrintTo(os); } }
128
129 #define CV_FLAGS(class_name, ...)                                                       \
130     namespace {                                                                         \
131     struct class_name {                                                                 \
132         class_name(int val = 0) : val_(val) {}                                          \
133         operator int() const { return val_; }                                           \
134         void PrintTo(std::ostream* os) const {                                          \
135             using namespace cv;using namespace cv::gpu; using namespace cv::ocl;        \
136             const int vals[] = { __VA_ARGS__ };                                         \
137             const char* svals = #__VA_ARGS__;                                           \
138             int value = val_;                                                           \
139             bool first = true;                                                          \
140             for(int i = 0, pos = 0; i < (int)(sizeof(vals)/sizeof(int)); ++i) {         \
141                 while(isspace(svals[pos]) || svals[pos] == ',') ++pos;                  \
142                 int start = pos;                                                        \
143                 while(!(isspace(svals[pos]) || svals[pos] == ',' || svals[pos] == 0))   \
144                     ++pos;                                                              \
145                 if ((value & vals[i]) == vals[i]) {                                     \
146                     value &= ~vals[i];                                                  \
147                     if (first) first = false; else *os << "|";                          \
148                     *os << std::string(svals + start, svals + pos);                     \
149                     if (!value) return;                                                 \
150                 }                                                                       \
151             }                                                                           \
152             if (first) *os << "UNKNOWN";                                                \
153         }                                                                               \
154     private: int val_;                                                                  \
155     };                                                                                  \
156     inline void PrintTo(const class_name& t, std::ostream* os) { t.PrintTo(os); } }
157
158 CV_ENUM(MatDepth, CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F, CV_USRTYPE1)
159
160 /*****************************************************************************************\
161 *                 Regression control utility for performance testing                      *
162 \*****************************************************************************************/
163 enum ERROR_TYPE
164 {
165     ERROR_ABSOLUTE = 0,
166     ERROR_RELATIVE = 1
167 };
168
169 class CV_EXPORTS Regression
170 {
171 public:
172     static Regression& add(TestBase* test, const std::string& name, cv::InputArray array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE);
173     static Regression& addKeypoints(TestBase* test, const std::string& name, const std::vector<cv::KeyPoint>& array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE);
174     static Regression& addMatches(TestBase* test, const std::string& name, const std::vector<cv::DMatch>& array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE);
175     static void Init(const std::string& testSuitName, const std::string& ext = ".xml");
176
177     Regression& operator() (const std::string& name, cv::InputArray array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE);
178
179 private:
180     static Regression& instance();
181     Regression();
182     ~Regression();
183
184     Regression(const Regression&);
185     Regression& operator=(const Regression&);
186
187     cv::RNG regRNG;//own random numbers generator to make collection and verification work identical
188     std::string storageInPath;
189     std::string storageOutPath;
190     cv::FileStorage storageIn;
191     cv::FileStorage storageOut;
192     cv::FileNode rootIn;
193     std::string currentTestNodeName;
194     std::string suiteName;
195
196     cv::FileStorage& write();
197
198     static std::string getCurrentTestNodeName();
199     static bool isVector(cv::InputArray a);
200     static double getElem(cv::Mat& m, int x, int y, int cn = 0);
201
202     void init(const std::string& testSuitName, const std::string& ext);
203     void write(cv::InputArray array);
204     void write(cv::Mat m);
205     void verify(cv::FileNode node, cv::InputArray array, double eps, ERROR_TYPE err);
206     void verify(cv::FileNode node, cv::Mat actual, double eps, std::string argname, ERROR_TYPE err);
207 };
208
209 #define SANITY_CHECK(array, ...) ::perf::Regression::add(this, #array, array , ## __VA_ARGS__)
210 #define SANITY_CHECK_KEYPOINTS(array, ...) ::perf::Regression::addKeypoints(this, #array, array , ## __VA_ARGS__)
211 #define SANITY_CHECK_MATCHES(array, ...) ::perf::Regression::addMatches(this, #array, array , ## __VA_ARGS__)
212 #define SANITY_CHECK_NOTHING() this->setVerified();
213
214 class CV_EXPORTS GpuPerf
215 {
216 public:
217   static bool targetDevice();
218 };
219
220 #define PERF_RUN_GPU()  ::perf::GpuPerf::targetDevice()
221
222 /*****************************************************************************************\
223 *                            Container for performance metrics                            *
224 \*****************************************************************************************/
225 typedef struct CV_EXPORTS performance_metrics
226 {
227     size_t bytesIn;
228     size_t bytesOut;
229     unsigned int samples;
230     unsigned int outliers;
231     double gmean;
232     double gstddev;//stddev for log(time)
233     double mean;
234     double stddev;
235     double median;
236     double min;
237     double frequency;
238     int terminationReason;
239
240     enum
241     {
242         TERM_ITERATIONS = 0,
243         TERM_TIME = 1,
244         TERM_INTERRUPT = 2,
245         TERM_EXCEPTION = 3,
246         TERM_SKIP_TEST = 4, // there are some limitations and test should be skipped
247         TERM_UNKNOWN = -1
248     };
249
250     performance_metrics();
251     void clear();
252 } performance_metrics;
253
254
255 /*****************************************************************************************\
256 *                           Strategy for performance measuring                            *
257 \*****************************************************************************************/
258 enum PERF_STRATEGY
259 {
260     PERF_STRATEGY_BASE = 0,
261     PERF_STRATEGY_SIMPLE = 1,
262 };
263
264
265 /*****************************************************************************************\
266 *                           Base fixture for performance tests                            *
267 \*****************************************************************************************/
268 class CV_EXPORTS TestBase: public ::testing::Test
269 {
270 public:
271     TestBase();
272
273     static void Init(int argc, const char* const argv[]);
274     static void Init(const std::vector<std::string> & availableImpls,
275                      int argc, const char* const argv[]);
276     static void RecordRunParameters();
277     static std::string getDataPath(const std::string& relativePath);
278     static std::string getSelectedImpl();
279
280     static enum PERF_STRATEGY getPerformanceStrategy();
281     static enum PERF_STRATEGY setPerformanceStrategy(enum PERF_STRATEGY strategy);
282
283     class PerfSkipTestException: public cv::Exception {};
284
285 protected:
286     virtual void PerfTestBody() = 0;
287
288     virtual void SetUp();
289     virtual void TearDown();
290
291     void startTimer();
292     void stopTimer();
293     bool next();
294
295     //_declareHelper declare;
296
297     enum
298     {
299         WARMUP_READ,
300         WARMUP_WRITE,
301         WARMUP_RNG,
302         WARMUP_NONE
303     };
304
305     void reportMetrics(bool toJUnitXML = false);
306     static void warmup(cv::InputOutputArray a, int wtype = WARMUP_READ);
307
308     performance_metrics& calcMetrics();
309     void RunPerfTestBody();
310 private:
311     typedef std::vector<std::pair<int, cv::Size> > SizeVector;
312     typedef std::vector<int64> TimeVector;
313
314     SizeVector inputData;
315     SizeVector outputData;
316     unsigned int getTotalInputSize() const;
317     unsigned int getTotalOutputSize() const;
318
319     TimeVector times;
320     int64 lastTime;
321     int64 totalTime;
322     int64 timeLimit;
323     static int64 timeLimitDefault;
324     static unsigned int iterationsLimitDefault;
325
326     unsigned int nIters;
327     unsigned int currentIter;
328     unsigned int runsPerIteration;
329
330     performance_metrics metrics;
331     void validateMetrics();
332
333     static int64 _timeadjustment;
334     static int64 _calibrate();
335
336     static void warmup_impl(cv::Mat m, int wtype);
337     static int getSizeInBytes(cv::InputArray a);
338     static cv::Size getSize(cv::InputArray a);
339     static void declareArray(SizeVector& sizes, cv::InputOutputArray a, int wtype = 0);
340
341     class CV_EXPORTS _declareHelper
342     {
343     public:
344         _declareHelper& in(cv::InputOutputArray a1, int wtype = WARMUP_READ);
345         _declareHelper& in(cv::InputOutputArray a1, cv::InputOutputArray a2, int wtype = WARMUP_READ);
346         _declareHelper& in(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, int wtype = WARMUP_READ);
347         _declareHelper& in(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, cv::InputOutputArray a4, int wtype = WARMUP_READ);
348
349         _declareHelper& out(cv::InputOutputArray a1, int wtype = WARMUP_WRITE);
350         _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, int wtype = WARMUP_WRITE);
351         _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, int wtype = WARMUP_WRITE);
352         _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, cv::InputOutputArray a4, int wtype = WARMUP_WRITE);
353
354         _declareHelper& iterations(unsigned int n);
355         _declareHelper& time(double timeLimitSecs);
356         _declareHelper& tbb_threads(int n = -1);
357         _declareHelper& runs(unsigned int runsNumber);
358     private:
359         TestBase* test;
360         _declareHelper(TestBase* t);
361         _declareHelper(const _declareHelper&);
362         _declareHelper& operator=(const _declareHelper&);
363         friend class TestBase;
364     };
365     friend class _declareHelper;
366
367     bool verified;
368
369 public:
370     _declareHelper declare;
371
372     void setVerified() { this->verified = true; }
373 };
374
375 template<typename T> class TestBaseWithParam: public TestBase, public ::testing::WithParamInterface<T> {};
376
377 typedef std::tr1::tuple<cv::Size, MatType> Size_MatType_t;
378 typedef TestBaseWithParam<Size_MatType_t> Size_MatType;
379
380 /*****************************************************************************************\
381 *                              Print functions for googletest                             *
382 \*****************************************************************************************/
383 CV_EXPORTS void PrintTo(const MatType& t, std::ostream* os);
384
385 } //namespace perf
386
387 namespace cv
388 {
389
390 CV_EXPORTS void PrintTo(const Size& sz, ::std::ostream* os);
391
392 } //namespace cv
393
394
395 /*****************************************************************************************\
396 *                        Macro definitions for performance tests                          *
397 \*****************************************************************************************/
398 #define PERF_PROXY_NAMESPACE_NAME_(test_case_name, test_name) \
399   test_case_name##_##test_name##_perf_namespace_proxy
400
401 // Defines a performance test.
402 //
403 // The first parameter is the name of the test case, and the second
404 // parameter is the name of the test within the test case.
405 //
406 // The user should put his test code between braces after using this
407 // macro.  Example:
408 //
409 //   PERF_TEST(FooTest, InitializesCorrectly) {
410 //     Foo foo;
411 //     EXPECT_TRUE(foo.StatusIsOK());
412 //   }
413 #define PERF_TEST(test_case_name, test_name)\
414     namespace PERF_PROXY_NAMESPACE_NAME_(test_case_name, test_name) {\
415      class TestBase {/*compile error for this class means that you are trying to use perf::TestBase as a fixture*/};\
416      class test_case_name : public ::perf::TestBase {\
417       public:\
418        test_case_name() {}\
419       protected:\
420        virtual void PerfTestBody();\
421      };\
422      TEST_F(test_case_name, test_name){ RunPerfTestBody(); }\
423     }\
424     void PERF_PROXY_NAMESPACE_NAME_(test_case_name, test_name)::test_case_name::PerfTestBody()
425
426 // Defines a performance test that uses a test fixture.
427 //
428 // The first parameter is the name of the test fixture class, which
429 // also doubles as the test case name.  The second parameter is the
430 // name of the test within the test case.
431 //
432 // A test fixture class must be declared earlier.  The user should put
433 // his test code between braces after using this macro.  Example:
434 //
435 //   class FooTest : public ::perf::TestBase {
436 //    protected:
437 //     virtual void SetUp() { TestBase::SetUp(); b_.AddElement(3); }
438 //
439 //     Foo a_;
440 //     Foo b_;
441 //   };
442 //
443 //   PERF_TEST_F(FooTest, InitializesCorrectly) {
444 //     EXPECT_TRUE(a_.StatusIsOK());
445 //   }
446 //
447 //   PERF_TEST_F(FooTest, ReturnsElementCountCorrectly) {
448 //     EXPECT_EQ(0, a_.size());
449 //     EXPECT_EQ(1, b_.size());
450 //   }
451 #define PERF_TEST_F(fixture, testname) \
452     namespace PERF_PROXY_NAMESPACE_NAME_(fixture, testname) {\
453      class TestBase {/*compile error for this class means that you are trying to use perf::TestBase as a fixture*/};\
454      class fixture : public ::fixture {\
455       public:\
456        fixture() {}\
457       protected:\
458        virtual void PerfTestBody();\
459      };\
460      TEST_F(fixture, testname){ RunPerfTestBody(); }\
461     }\
462     void PERF_PROXY_NAMESPACE_NAME_(fixture, testname)::fixture::PerfTestBody()
463
464 // Defines a parametrized performance test.
465 //
466 // The first parameter is the name of the test fixture class, which
467 // also doubles as the test case name.  The second parameter is the
468 // name of the test within the test case.
469 //
470 // The user should put his test code between braces after using this
471 // macro.  Example:
472 //
473 //   typedef ::perf::TestBaseWithParam<cv::Size> FooTest;
474 //
475 //   PERF_TEST_P(FooTest, DoTestingRight, ::testing::Values(::perf::szVGA, ::perf::sz720p) {
476 //     cv::Mat b(GetParam(), CV_8U, cv::Scalar(10));
477 //     cv::Mat a(GetParam(), CV_8U, cv::Scalar(20));
478 //     cv::Mat c(GetParam(), CV_8U, cv::Scalar(0));
479 //
480 //     declare.in(a, b).out(c).time(0.5);
481 //
482 //     TEST_CYCLE() cv::add(a, b, c);
483 //
484 //     SANITY_CHECK(c);
485 //   }
486 #define PERF_TEST_P(fixture, name, params)  \
487     class fixture##_##name : public fixture {\
488      public:\
489       fixture##_##name() {}\
490      protected:\
491       virtual void PerfTestBody();\
492     };\
493     TEST_P(fixture##_##name, name /*perf*/){ RunPerfTestBody(); }\
494     INSTANTIATE_TEST_CASE_P(/*none*/, fixture##_##name, params);\
495     void fixture##_##name::PerfTestBody()
496
497 #ifndef __CV_TEST_EXEC_ARGS
498 #if defined(_MSC_VER) && (_MSC_VER <= 1400)
499 #define __CV_TEST_EXEC_ARGS(...)    \
500     while (++argc >= (--argc,-1)) {__VA_ARGS__; break;} /*this ugly construction is needed for VS 2005*/
501 #else
502 #define __CV_TEST_EXEC_ARGS(...)    \
503     __VA_ARGS__;
504 #endif
505 #endif
506
507 #define CV_PERF_TEST_MAIN_INTERNALS(modulename, impls, ...)     \
508     ::perf::Regression::Init(#modulename); \
509     ::perf::TestBase::Init(std::vector<std::string>(impls, impls + sizeof impls / sizeof *impls), \
510                            argc, argv); \
511     ::testing::InitGoogleTest(&argc, argv); \
512     cvtest::printVersionInfo(); \
513     ::testing::Test::RecordProperty("cv_module_name", #modulename); \
514     ::perf::TestBase::RecordRunParameters(); \
515     __CV_TEST_EXEC_ARGS(__VA_ARGS__) \
516     return RUN_ALL_TESTS();
517
518 // impls must be an array, not a pointer; "plain" should always be one of the implementations
519 #define CV_PERF_TEST_MAIN_WITH_IMPLS(modulename, impls, ...) \
520 int main(int argc, char **argv)\
521 {\
522     CV_PERF_TEST_MAIN_INTERNALS(modulename, impls, __VA_ARGS__)\
523 }
524
525 #define CV_PERF_TEST_MAIN(modulename, ...) \
526 int main(int argc, char **argv)\
527 {\
528     const char * plain_only[] = { "plain" };\
529     CV_PERF_TEST_MAIN_INTERNALS(modulename, plain_only, __VA_ARGS__)\
530 }
531
532 #define TEST_CYCLE_N(n) for(declare.iterations(n); startTimer(), next(); stopTimer())
533 #define TEST_CYCLE() for(; startTimer(), next(); stopTimer())
534 #define TEST_CYCLE_MULTIRUN(runsNum) for(declare.runs(runsNum); startTimer(), next(); stopTimer()) for(int r = 0; r < runsNum; ++r)
535
536 namespace perf
537 {
538 namespace comparators
539 {
540
541 template<typename T>
542 struct CV_EXPORTS RectLess_
543 {
544   bool operator()(const cv::Rect_<T>& r1, const cv::Rect_<T>& r2) const
545   {
546     return r1.x < r2.x
547       || (r1.x == r2.x && r1.y < r2.y)
548       || (r1.x == r2.x && r1.y == r2.y && r1.width < r2.width)
549       || (r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height < r2.height);
550   }
551 };
552
553 typedef RectLess_<int> RectLess;
554
555 struct CV_EXPORTS KeypointGreater
556 {
557     bool operator()(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2) const
558     {
559         if(kp1.response > kp2.response) return true;
560         if(kp1.response < kp2.response) return false;
561         if(kp1.size > kp2.size) return true;
562         if(kp1.size < kp2.size) return false;
563         if(kp1.octave > kp2.octave) return true;
564         if(kp1.octave < kp2.octave) return false;
565         if(kp1.pt.y < kp2.pt.y) return false;
566         if(kp1.pt.y > kp2.pt.y) return true;
567         return kp1.pt.x < kp2.pt.x;
568     }
569 };
570
571 } //namespace comparators
572
573 void CV_EXPORTS sort(std::vector<cv::KeyPoint>& pts, cv::InputOutputArray descriptors);
574 } //namespace perf
575
576 #endif //__OPENCV_TS_PERF_HPP__