1 #include "test_precomp.hpp"
6 struct CV_EXPORTS L2Fake : public L2<float>
8 enum { normType = NORM_L2 };
11 class CV_BruteForceMatcherTest : public cvtest::BaseTest
14 CV_BruteForceMatcherTest() {}
18 const int dimensions = 64;
19 const int descriptorsNumber = 5000;
21 Mat train = Mat( descriptorsNumber, dimensions, CV_32FC1);
22 Mat query = Mat( descriptorsNumber, dimensions, CV_32FC1);
24 Mat permutation( 1, descriptorsNumber, CV_32SC1 );
25 for( int i=0;i<descriptorsNumber;i++ )
26 permutation.at<int>( 0, i ) = i;
28 //RNG rng = RNG( cvGetTickCount() );
30 randShuffle( permutation, 1, &rng );
32 float boundary = 500.f;
33 for( int row=0;row<descriptorsNumber;row++ )
35 for( int col=0;col<dimensions;col++ )
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 );
43 vector<DMatch> specMatches, genericMatches;
44 BruteForceMatcher<L2<float> > specMatcher;
45 BruteForceMatcher<L2Fake > genericMatcher;
47 int64 time0 = cvGetTickCount();
48 specMatcher.match( query, train, specMatches );
49 int64 time1 = cvGetTickCount();
50 genericMatcher.match( query, train, genericMatches );
51 int64 time2 = cvGetTickCount();
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 ) );
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 ) );
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++ )
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 ) )
71 ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
78 Mat mask( query.rows, train.rows, CV_8UC1 );
79 rng.fill( mask, RNG::UNIFORM, 0, 2 );
82 time0 = cvGetTickCount();
83 specMatcher.match( query, train, specMatches, mask );
84 time1 = cvGetTickCount();
85 genericMatcher.match( query, train, genericMatches, mask );
86 time2 = cvGetTickCount();
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 ) );
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 ) );
96 if( specMatches.size() != genericMatches.size() )
97 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
99 for( size_t i=0;i<specMatches.size();i++ )
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;
108 ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
115 TEST(Legacy_BruteForceMatcher, accuracy) { CV_BruteForceMatcherTest test; test.safe_run(); }