Skip to content

Commit a3f8397

Browse files
committed
More test cases
1 parent 8fdc51a commit a3f8397

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed

test/flann_kdtree_single_test.cpp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,217 @@ TEST_F(KDTreeSingle, TestCopy2)
353353
EXPECT_EQ(precision, precision5);
354354
}
355355

356+
TEST_F(KDTreeSingle, TestNoNeighbours)
357+
{
358+
flann::Index<L2_Simple<float> > index(data, flann::KDTreeSingleIndexParams(12, false));
359+
start_timer("Building kd-tree index...");
360+
index.buildIndex();
361+
printf("done (%g seconds)\n", stop_timer());
362+
363+
start_timer("Searching KNN...");
364+
index.knnSearch(query, indices, dists, knn, flann::SearchParams(-1) );
365+
printf("done (%g seconds)\n", stop_timer());
366+
367+
368+
float min_dist = dists[0][0];
369+
for (size_t i=0;i<query.rows;++i) {
370+
min_dist = std::min(min_dist, dists[i][0]);
371+
}
372+
373+
printf("Minimum distance: %g\n", min_dist);
374+
375+
start_timer("Searching radius smaller than minimum distance...");
376+
int count = index.radiusSearch(query, indices, dists, min_dist/2, flann::SearchParams(-1) );
377+
printf("done (%g seconds)\n", stop_timer());
378+
379+
EXPECT_EQ(0,count);
380+
for (size_t i=0;i<dists.rows;++i) {
381+
EXPECT_EQ(dists[i][0],std::numeric_limits<float>::infinity());
382+
}
383+
384+
std::vector<std::vector<size_t> > indices2;
385+
std::vector<std::vector<float> > dists2;
386+
start_timer("Searching radius smaller than minimum distance...");
387+
int count2 = index.radiusSearch(query, indices2, dists2, min_dist/2, flann::SearchParams(-1) );
388+
printf("done (%g seconds)\n", stop_timer());
389+
390+
EXPECT_EQ(0,count2);
391+
for (size_t i=0;i<indices2.size();++i) {
392+
EXPECT_EQ(indices2[i].size(),0);
393+
}
394+
}
395+
396+
397+
// Test cases for 3D point clouds, borrowed from PCL test_kdtree
398+
struct MyPoint
399+
{
400+
MyPoint (float x, float y, float z) {this->x=x; this->y=y; this->z=z;}
401+
402+
float x,y,z;
403+
};
404+
405+
406+
class KDTreeSinglePointCloud : public FLANNTestFixture
407+
{
408+
public:
409+
void SetUp()
410+
{
411+
float resolution = 0.1f;
412+
for (float z = -0.5f; z <= 0.5f; z += resolution)
413+
for (float y = -0.5f; y <= 0.5f; y += resolution)
414+
for (float x = -0.5f; x <= 0.5f; x += resolution)
415+
cloud_.push_back (MyPoint (x, y, z));
416+
417+
cloud_mat_ = flann::Matrix<float>(&cloud_[0].x, cloud_.size(), 3);
418+
419+
420+
srand(static_cast<unsigned int> (time (NULL)));
421+
// Randomly create a new point cloud
422+
for (size_t i = 0; i < 640*480; ++i)
423+
cloud_big_.push_back (MyPoint (static_cast<float> (1024 * rand () / (RAND_MAX + 1.0)),
424+
static_cast<float> (1024 * rand () / (RAND_MAX + 1.0)),
425+
static_cast<float> (1024 * rand () / (RAND_MAX + 1.0))));
426+
427+
428+
cloud_big_mat_ = flann::Matrix<float>(&cloud_big_[0].x, cloud_big_.size(), 3);
429+
}
430+
431+
std::vector<MyPoint> cloud_;
432+
flann::Matrix<float> cloud_mat_;
433+
434+
std::vector<MyPoint> cloud_big_;
435+
flann::Matrix<float> cloud_big_mat_;
436+
};
437+
438+
TEST_F(KDTreeSinglePointCloud, TestRadiusSearch)
439+
{
440+
std::vector<std::vector<int> > k_indices;
441+
std::vector<std::vector<float> > k_distances;
442+
443+
{
444+
flann::Index<L2_Simple<float> > index(cloud_mat_, flann::KDTreeSingleIndexParams(12, false));
445+
index.buildIndex();
446+
447+
L2_Simple<float> euclideanDistance;
448+
MyPoint test_point(0.0f, 0.0f, 0.0f);
449+
flann::Matrix<float> test_mat(&test_point.x, 1, 3);
450+
double max_dist = 0.15*0.15;
451+
std::set<int> brute_force_result;
452+
for (unsigned int i=0; i<cloud_mat_.rows; ++i)
453+
if (euclideanDistance(cloud_mat_[i], test_mat[0], 3) < max_dist)
454+
brute_force_result.insert(i);
455+
index.radiusSearch (test_mat, k_indices, k_distances, max_dist, flann::SearchParams(-1));
456+
457+
for (size_t i = 0; i < k_indices[0].size (); ++i)
458+
{
459+
std::set<int>::iterator brute_force_result_it = brute_force_result.find (k_indices[0][i]);
460+
bool ok = brute_force_result_it != brute_force_result.end ();
461+
//if (!ok) cerr << k_indices[i] << " is not correct...\n";
462+
//else cerr << k_indices[i] << " is correct...\n";
463+
EXPECT_EQ (ok, true);
464+
if (ok)
465+
brute_force_result.erase (brute_force_result_it);
466+
}
467+
//for (set<int>::const_iterator it=brute_force_result.begin(); it!=brute_force_result.end(); ++it)
468+
//cerr << "FLANN missed "<<*it<<"\n";
469+
470+
bool error = brute_force_result.size () > 0;
471+
//if (error) cerr << "Missed too many neighbors!\n";
472+
EXPECT_EQ (error, false);
473+
}
474+
475+
{
476+
flann::Index<L2_Simple<float> > index(flann::KDTreeSingleIndexParams(15));
477+
index.buildIndex(cloud_big_mat_);
478+
479+
start_timer("radiusSearch...");
480+
flann::SearchParams params(-1);
481+
index.radiusSearch(cloud_big_mat_, k_indices, k_distances, 0.1*0.1, params);
482+
printf("done (%g seconds)\n", stop_timer());
483+
}
484+
485+
{
486+
flann::Index<L2_Simple<float> > index(flann::KDTreeSingleIndexParams(15));
487+
index.buildIndex(cloud_big_mat_);
488+
489+
start_timer("radiusSearch (max neighbors in radius)...");
490+
flann::SearchParams params(-1);
491+
params.max_neighbors = 10;
492+
index.radiusSearch(cloud_big_mat_, k_indices, k_distances, 0.1*0.1, params);
493+
printf("done (%g seconds)\n", stop_timer());
494+
}
495+
496+
{
497+
flann::Index<L2_Simple<float> > index(flann::KDTreeSingleIndexParams(15));
498+
index.buildIndex(cloud_big_mat_);
499+
500+
start_timer("radiusSearch (unsorted results)...");
501+
flann::SearchParams params(-1);
502+
params.sorted = false;
503+
index.radiusSearch(cloud_big_mat_, k_indices, k_distances, 0.1*0.1, params);
504+
printf("done (%g seconds)\n", stop_timer());
505+
}
506+
}
507+
508+
509+
TEST_F(KDTreeSinglePointCloud, TestKNearestSearch)
510+
{
511+
unsigned int no_of_neighbors = 20;
512+
513+
{
514+
flann::Index<L2_Simple<float> > index(cloud_mat_, flann::KDTreeSingleIndexParams(12, false));
515+
index.buildIndex();
516+
517+
L2_Simple<float> euclideanDistance;
518+
MyPoint test_point (0.01f, 0.01f, 0.01f);
519+
flann::Matrix<float> test_mat(&test_point.x, 1, 3);
520+
521+
std:: multimap<float, int> sorted_brute_force_result;
522+
for (size_t i = 0; i < cloud_.size (); ++i)
523+
{
524+
float distance = euclideanDistance (cloud_mat_[i], test_mat[0],3);
525+
sorted_brute_force_result.insert (std::make_pair (distance, static_cast<int> (i)));
526+
}
527+
float max_dist = 0.0f;
528+
unsigned int counter = 0;
529+
for (std::multimap<float, int>::iterator it = sorted_brute_force_result.begin (); it != sorted_brute_force_result.end () && counter < no_of_neighbors; ++it)
530+
{
531+
max_dist = std::max (max_dist, it->first);
532+
++counter;
533+
}
534+
535+
std::vector< std::vector<int> > k_indices(1);
536+
k_indices[0].resize (no_of_neighbors);
537+
std::vector<std::vector<float> > k_distances(1);
538+
k_distances[0].resize (no_of_neighbors);
539+
index.knnSearch(test_mat, k_indices, k_distances, no_of_neighbors, flann::SearchParams(-1));
540+
//if (k_indices.size() != no_of_neighbors) cerr << "Found "<<k_indices.size()<<" instead of "<<no_of_neighbors<<" neighbors.\n";
541+
EXPECT_EQ (k_indices[0].size (), no_of_neighbors);
542+
543+
// Check if all found neighbors have distance smaller than max_dist
544+
for (size_t i = 0; i < k_indices[0].size (); ++i)
545+
{
546+
float* point = cloud_mat_[k_indices[0][i]];
547+
bool ok = euclideanDistance (test_mat[0], point, 3) <= max_dist;
548+
EXPECT_EQ (ok, true);
549+
}
550+
}
551+
552+
{
553+
flann::Index<L2_Simple<float> > index(flann::KDTreeSingleIndexParams(15));
554+
index.buildIndex(cloud_big_mat_);
555+
556+
start_timer("K nearest neighbour search...");
557+
flann::SearchParams params(-1);
558+
params.sorted = false;
559+
std::vector<std::vector<int> > k_indices;
560+
std::vector<std::vector<float> > k_distances;
561+
index.knnSearch (cloud_big_mat_, k_indices, k_distances, no_of_neighbors, params);
562+
printf("done (%g seconds)\n", stop_timer());
563+
}
564+
565+
}
566+
356567
int main(int argc, char** argv)
357568
{
358569
testing::InitGoogleTest(&argc, argv);

0 commit comments

Comments
 (0)