1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
50 using namespace cv::flann;
52 //--------------------------------------------------------------------------------
53 class NearestNeighborTest : public CvTest
56 NearestNeighborTest( const char* test_name, const char* test_funcs )
57 : CvTest( test_name, test_funcs ) {}
59 virtual void run( int start_from );
60 virtual void createModel( const Mat& data ) = 0;
61 virtual void searchNeighbors( Mat& points, Mat& neighbors ) = 0;
62 virtual void releaseModel() = 0;
65 void NearestNeighborTest::run( int /*start_from*/ ) {
67 int featuresCount = 2000;
68 int K = 1; // * should also test 2nd nn etc.?
70 int pointsCount = 1000;
73 Mat desc( featuresCount, dims, CV_32FC1 );
74 rng.fill( desc, RNG::UNIFORM, Scalar(0.0f), Scalar(1.0f) );
78 Mat points( pointsCount, dims, CV_32FC1 );
79 Mat results( pointsCount, K, CV_32SC1 );
81 std::vector<int> fmap( pointsCount );
82 for( int pi = 0; pi < pointsCount; pi++ )
84 int fi = rng.next() % featuresCount;
86 for( int d = 0; d < dims; d++ )
87 points.at<float>(pi, d) = desc.at<float>(fi, d) + rng.uniform(0.0f, 1.0f) * noise;
89 searchNeighbors( points, results );
93 int correctMatches = 0;
94 for( int pi = 0; pi < pointsCount; pi++ )
96 if( fmap[pi] == results.at<int>(pi, 0) )
100 double correctPerc = correctMatches / (double)pointsCount;
101 ts->printf( CvTS::LOG, "correct_perc = %d\n", correctPerc );
102 if (correctPerc < .8)
103 ts->set_failed_test_info(CvTS::FAIL_INVALID_OUTPUT);
106 //--------------------------------------------------------------------------------
107 class CV_LSHTest : public NearestNeighborTest
110 CV_LSHTest() : NearestNeighborTest( "lsh", "cvLSHQuery" ) {}
112 virtual void createModel( const Mat& data );
113 virtual void searchNeighbors( Mat& points, Mat& neighbors );
114 virtual void releaseModel();
119 void CV_LSHTest::createModel( const Mat& data )
122 lsh = cvCreateMemoryLSH( data.cols, data.rows, 70, 20, CV_32FC1 );
123 cvLSHAdd( lsh, &desc );
126 void CV_LSHTest::searchNeighbors( Mat& points, Mat& neighbors )
129 Mat dist( points.rows, neighbors.cols, CV_64FC1);
130 CvMat _dist = dist, _points = points, _neighbors = neighbors;
131 cvLSHQuery( lsh, &_points, &_neighbors, &_dist, neighbors.cols, emax );
134 void CV_LSHTest::releaseModel()
136 cvReleaseLSH( &lsh );
139 //--------------------------------------------------------------------------------
140 class CV_FeatureTreeTest_C : public NearestNeighborTest
143 CV_FeatureTreeTest_C( const char* test_name, const char* test_funcs )
144 : NearestNeighborTest( test_name, test_funcs ) {}
146 virtual void searchNeighbors( Mat& points, Mat& neighbors );
147 virtual void releaseModel();
152 void CV_FeatureTreeTest_C::searchNeighbors( Mat& points, Mat& neighbors )
155 Mat dist( points.rows, neighbors.cols, CV_64FC1);
156 CvMat _dist = dist, _points = points, _neighbors = neighbors;
157 cvFindFeatures( tr, &_points, &_neighbors, &_dist, neighbors.cols, emax );
160 void CV_FeatureTreeTest_C::releaseModel()
162 cvReleaseFeatureTree( tr );
165 //--------------------------------------
166 class CV_SpillTreeTest_C : public CV_FeatureTreeTest_C
169 CV_SpillTreeTest_C(): CV_FeatureTreeTest_C( "spilltree_c", "cvFindFeatures-spill" ) {}
171 virtual void createModel( const Mat& data );
174 void CV_SpillTreeTest_C::createModel( const Mat& data )
177 tr = cvCreateSpillTree( &desc );
180 //--------------------------------------
181 class CV_KDTreeTest_C : public CV_FeatureTreeTest_C
184 CV_KDTreeTest_C(): CV_FeatureTreeTest_C( "kdtree_c", "cvFindFeatures-kd" ) {}
186 virtual void createModel( const Mat& data );
189 void CV_KDTreeTest_C::createModel( const Mat& data )
192 tr = cvCreateKDTree( &desc );
195 //--------------------------------------------------------------------------------
196 class CV_KDTreeTest_CPP : public NearestNeighborTest
199 CV_KDTreeTest_CPP() : NearestNeighborTest( "kdtree_cpp", "cv::KDTree funcs" ) {}
201 virtual void createModel( const Mat& data );
202 virtual void searchNeighbors( Mat& points, Mat& neighbors );
203 virtual void releaseModel();
207 void CV_KDTreeTest_CPP::createModel( const Mat& data )
209 tr = new KDTree( data );
212 void CV_KDTreeTest_CPP::searchNeighbors( Mat& points, Mat& neighbors )
215 for( int pi = 0; pi < points.rows; pi++ )
216 tr->findNearest( points.ptr<float>(pi), neighbors.cols, emax, neighbors.ptr<int>(pi) );
219 void CV_KDTreeTest_CPP::releaseModel()
224 //--------------------------------------------------------------------------------
225 class CV_FlannTest : public NearestNeighborTest
228 CV_FlannTest( const char* test_name, const char* test_funcs )
229 : NearestNeighborTest( test_name, test_funcs ) {}
231 void createIndex( const Mat& data, const IndexParams& params );
232 void knnSearch( Mat& points, Mat& neighbors );
233 void radiusSearch( Mat& points, Mat& neighbors );
234 virtual void releaseModel();
238 void CV_FlannTest::createIndex( const Mat& data, const IndexParams& params )
240 index = new Index( data, params );
243 void CV_FlannTest::knnSearch( Mat& points, Mat& neighbors )
245 Mat dist( points.rows, neighbors.cols, CV_32FC1);
246 index->knnSearch( points, neighbors, dist, 1, SearchParams() );
249 void CV_FlannTest::radiusSearch( Mat& points, Mat& neighbors )
251 Mat dist( 1, neighbors.cols, CV_32FC1);
252 // radiusSearch can only search one feature at a time for range search
253 for( int i = 0; i < points.rows; i++ )
255 Mat p( 1, points.cols, CV_32FC1, points.ptr<float>(i) ),
256 n( 1, neighbors.cols, CV_32SC1, neighbors.ptr<int>(i) );
257 index->radiusSearch( p, n, dist, 10.0f, SearchParams() );
261 void CV_FlannTest::releaseModel()
266 //---------------------------------------
267 class CV_FlannLinearIndexTest : public CV_FlannTest
270 CV_FlannLinearIndexTest() : CV_FlannTest( "flann_linear", "LinearIndex" ) {}
272 virtual void createModel( const Mat& data ) { createIndex( data, LinearIndexParams() ); }
273 virtual void searchNeighbors( Mat& points, Mat& neighbors ) { knnSearch( points, neighbors ); }
276 //---------------------------------------
277 class CV_FlannKMeansIndexTest : public CV_FlannTest
280 CV_FlannKMeansIndexTest() : CV_FlannTest( "flann_kmeans", "KMeansIndex" ) {}
282 virtual void createModel( const Mat& data ) { createIndex( data, KMeansIndexParams() ); }
283 virtual void searchNeighbors( Mat& points, Mat& neighbors ) { radiusSearch( points, neighbors ); }
286 //---------------------------------------
287 class CV_FlannKDTreeIndexTest : public CV_FlannTest
290 CV_FlannKDTreeIndexTest() : CV_FlannTest( "flann_kdtree", "KDTreeIndex" ) {}
292 virtual void createModel( const Mat& data ) { createIndex( data, KDTreeIndexParams() ); }
293 virtual void searchNeighbors( Mat& points, Mat& neighbors ) { radiusSearch( points, neighbors ); }
296 //----------------------------------------
297 class CV_FlannAutotunedIndexTest : public CV_FlannTest
300 CV_FlannAutotunedIndexTest() : CV_FlannTest( "flann_autotuned", "AutotunedIndex" ) {}
302 virtual void createModel( const Mat& data ) { createIndex( data, AutotunedIndexParams() ); }
303 virtual void searchNeighbors( Mat& points, Mat& neighbors ) { knnSearch( points, neighbors ); }
307 CV_SpillTreeTest_C spilltree_test_c;
308 CV_KDTreeTest_C kdtree_test_c;
309 CV_KDTreeTest_CPP kdtree_test_cpp;
310 CV_FlannLinearIndexTest flann_linear_index;
311 CV_FlannKMeansIndexTest flann_kmeans_index;
312 CV_FlannKDTreeIndexTest flann_kdtree_index;
313 CV_FlannAutotunedIndexTest flann_autotuned_index;