3259563e5626209a8344a0d8007eb6b5d34c49bc
[platform/upstream/opencv.git] / modules / legacy / test / test_bruteforcematcher.cpp
1 #include "test_precomp.hpp"
2
3 using namespace std;
4 using namespace cv;
5
6 struct CV_EXPORTS L2Fake : public L2<float>
7 {
8     enum { normType = NORM_L2 };
9 };
10
11 class CV_BruteForceMatcherTest : public cvtest::BaseTest
12 {
13 public:
14     CV_BruteForceMatcherTest() {}
15 protected:
16     void run( int )
17     {
18         const int dimensions = 64;
19         const int descriptorsNumber = 5000;
20
21         Mat train = Mat( descriptorsNumber, dimensions, CV_32FC1);
22         Mat query = Mat( descriptorsNumber, dimensions, CV_32FC1);
23
24         Mat permutation( 1, descriptorsNumber, CV_32SC1 );
25         for( int i=0;i<descriptorsNumber;i++ )
26             permutation.at<int>( 0, i ) = i;
27
28         //RNG rng = RNG( cvGetTickCount() );
29         RNG rng;
30         randShuffle( permutation, 1, &rng );
31
32         float boundary =  500.f;
33         for( int row=0;row<descriptorsNumber;row++ )
34         {
35             for( int col=0;col<dimensions;col++ )
36             {
37                 int bit = rng( 2 );
38                 train.at<float>( permutation.at<int>( 0, row ), col ) = bit*boundary + rng.uniform( 0.f, boundary );
39                 query.at<float>( row, col ) = bit*boundary + rng.uniform( 0.f, boundary );
40             }
41         }
42
43         vector<DMatch> specMatches, genericMatches;
44         BruteForceMatcher<L2<float> > specMatcher;
45         BruteForceMatcher<L2Fake > genericMatcher;
46
47         int64 time0 = cvGetTickCount();
48         specMatcher.match( query, train, specMatches );
49         int64 time1 = cvGetTickCount();
50         genericMatcher.match( query, train, genericMatches );
51         int64 time2 = cvGetTickCount();
52
53         float specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency();
54         ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time s: %f, us per pair: %f\n",
55                    specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) );
56
57         float genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency();
58         ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time s: %f, us per pair: %f\n",
59                    genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) );
60
61         if( (int)specMatches.size() != descriptorsNumber || (int)genericMatches.size() != descriptorsNumber )
62             ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
63         for( int i=0;i<descriptorsNumber;i++ )
64         {
65             float epsilon = 0.01f;
66             bool isEquiv = fabs( specMatches[i].distance - genericMatches[i].distance ) < epsilon &&
67                            specMatches[i].queryIdx == genericMatches[i].queryIdx &&
68                            specMatches[i].trainIdx == genericMatches[i].trainIdx;
69             if( !isEquiv || specMatches[i].trainIdx != permutation.at<int>( 0, i ) )
70             {
71                 ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
72                 break;
73             }
74         }
75
76
77         //Test mask
78         Mat mask( query.rows, train.rows, CV_8UC1 );
79         rng.fill( mask, RNG::UNIFORM, 0, 2 );
80
81
82         time0 = cvGetTickCount();
83         specMatcher.match( query, train, specMatches, mask );
84         time1 = cvGetTickCount();
85         genericMatcher.match( query, train, genericMatches, mask );
86         time2 = cvGetTickCount();
87
88         specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency();
89         ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time with mask s: %f, us per pair: %f\n",
90                    specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) );
91
92         genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency();
93         ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time with mask s: %f, us per pair: %f\n",
94                    genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) );
95
96         if( specMatches.size() != genericMatches.size() )
97             ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
98
99         for( size_t i=0;i<specMatches.size();i++ )
100         {
101             //float epsilon = 1e-2;
102             float epsilon = 10000000;
103             bool isEquiv = fabs( specMatches[i].distance - genericMatches[i].distance ) < epsilon &&
104                            specMatches[i].queryIdx == genericMatches[i].queryIdx &&
105                            specMatches[i].trainIdx == genericMatches[i].trainIdx;
106             if( !isEquiv )
107             {
108                 ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
109                 break;
110             }
111         }
112     }
113 };
114
115 TEST(Legacy_BruteForceMatcher, accuracy) { CV_BruteForceMatcherTest test; test.safe_run(); }