From e21d019c05dbbadaa60b12e0e88f88fd143637c8 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 1 Dec 2020 14:01:00 +0100 Subject: [PATCH] Finalize validity test --- .../test/Shape_detection/CMakeLists.txt | 2 - .../test/Shape_detection/test_validity.cpp | 197 ------------------ .../test_validity_sampled_data.cpp | 9 +- 3 files changed, 8 insertions(+), 200 deletions(-) delete mode 100644 Shape_detection/test/Shape_detection/test_validity.cpp diff --git a/Shape_detection/test/Shape_detection/CMakeLists.txt b/Shape_detection/test/Shape_detection/CMakeLists.txt index d5a4eca990a..49f314edeb8 100644 --- a/Shape_detection/test/Shape_detection/CMakeLists.txt +++ b/Shape_detection/test/Shape_detection/CMakeLists.txt @@ -15,7 +15,6 @@ include(CGAL_CreateSingleSourceCGALProgram) find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater) include(CGAL_Eigen_support) if(EIGEN3_FOUND) - create_single_source_cgal_program("test_validity.cpp") create_single_source_cgal_program("test_region_growing_basic.cpp") create_single_source_cgal_program("test_region_growing_on_cube.cpp") create_single_source_cgal_program("test_region_growing_on_point_set_2.cpp") @@ -31,7 +30,6 @@ if(EIGEN3_FOUND) "test_region_growing_on_degenerated_mesh.cpp") foreach( target - test_validity test_region_growing_basic test_region_growing_on_cube test_region_growing_on_point_set_2 diff --git a/Shape_detection/test/Shape_detection/test_validity.cpp b/Shape_detection/test/Shape_detection/test_validity.cpp deleted file mode 100644 index 3038082d850..00000000000 --- a/Shape_detection/test/Shape_detection/test_validity.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include - -//#define CGAL_RANSAC_EXPERIMENTAL_FIXES -#include -#include -#include - -#include - -#include - -#include - -namespace SD = CGAL::Shape_detection; - -using Kernel = CGAL::Simple_cartesian; -using Point_3 = Kernel::Point_3; -using Vector_3 = Kernel::Vector_3; - -using Pwn = std::pair; -using Point_set = std::vector; -using Point_map = CGAL::First_of_pair_property_map; -using Normal_map = CGAL::Second_of_pair_property_map; - -using RG_query = SD::Point_set::Sphere_neighbor_query; -using RG_region = SD::Point_set::Least_squares_plane_fit_region; -using Region_growing = SD::Region_growing; - -using RANSAC_traits = SD::Efficient_RANSAC_traits; -using RANSAC = SD::Efficient_RANSAC; -using RANSAC_plane = SD::Plane; - -void test_random_planes(std::size_t nb_planes); - -int main() -{ - // test_random_planes(1); - // test_random_planes(10); - // test_random_planes(100); - test_random_planes(1000); - test_random_planes(10000); - - return EXIT_SUCCESS; -} - -void test_random_planes(std::size_t nb_planes) -{ - CGAL::Random random; - std::cerr << "[TEST ON " << nb_planes << " RANDOM PLANES, SEED = " - << random.get_seed() << "] "; - - std::vector time_rg; - std::vector nb_detected_rg; - std::vector nb_unassigned_rg; - std::vector time_ransac; - std::vector nb_detected_ransac; - std::vector nb_unassigned_ransac; - - CGAL::Real_timer timer; - double timeout = 60.; // 1 minute timeout - - timer.start(); - std::size_t nb_runs = 100; - for (std::size_t run = 0; run < nb_runs; ++ run) - { - std::size_t min_points = random.get_int(10, 100); - std::size_t max_points = random.get_int(100, 1000); - double cluster_epsilon = random.get_double(0.01, 10.); - double epsilon = random.get_double (0., cluster_epsilon / 10.); - double normal_threshold = random.get_double (0.75, 0.99); - - double spacing = 0.8 * cluster_epsilon / std::sqrt(2); // smaller than diagonal - double domain_size = spacing * std::sqrt(nb_planes) * std::sqrt(0.5 * (min_points + max_points)) * 0.5; - double noise = 0.5 * epsilon; - - Point_set points; - for (std::size_t i = 0; i < nb_planes; ++ i) - { - // Generate random plane - Point_3 origin (random.get_double(-domain_size, domain_size), - random.get_double(-domain_size, domain_size), - random.get_double(-domain_size, domain_size)); - Vector_3 base1 (random.get_double(-1,1), random.get_double(-1,1), random.get_double(-1,1)); - base1 = base1 / std::sqrt(base1 * base1); - Vector_3 base2 (random.get_double(-1,1), random.get_double(-1,1), random.get_double(-1,1)); - base2 = base2 / std::sqrt(base2 * base2); - - Vector_3 normal = CGAL::cross_product (base1, base2); - normal = normal / std::sqrt (normal * normal); - - std::size_t nb_points = random.get_int (min_points, max_points); - - std::size_t nb_x = std::size_t(std::sqrt (double(nb_points))); - std::size_t nb_y = std::size_t(nb_points / double(nb_x)) + 1; - - for (std::size_t j = 0; j < nb_x; ++ j) - for (std::size_t k = 0; k < nb_y; ++ k) - points.emplace_back (origin + j * spacing * base1 + k * spacing * base2 - + normal * random.get_double(-noise/2, noise/2), - normal); - } - - // std::ofstream test("dump.pwn"); - // for (const auto& p : points) - // test << p.first << " " << p.second << std::endl; - CGAL::Real_timer t; - t.start(); - RG_query rg_query (points, cluster_epsilon); - RG_region rg_region (points, epsilon, normal_threshold, min_points); - Region_growing region_growing (points, rg_query, rg_region); - std::size_t nb_detected = 0; - std::size_t nb_unassigned = 0; - region_growing.detect (boost::make_function_output_iterator ([&](const auto&) { ++ nb_detected; })); - region_growing.unassigned_items (boost::make_function_output_iterator ([&](const auto&) { ++ nb_unassigned; })); - t.stop(); - - time_rg.push_back (t.time()); - nb_detected_rg.push_back (nb_detected); - nb_unassigned_rg.push_back (nb_unassigned / double(points.size())); - t.reset(); - - t.start(); - RANSAC ransac; - ransac.template add_shape_factory(); - ransac.set_input(points); - typename RANSAC::Parameters parameters; - parameters.probability = 0.05f; - parameters.min_points = min_points; - parameters.epsilon = epsilon; - parameters.cluster_epsilon = cluster_epsilon; - parameters.normal_threshold = normal_threshold; - ransac.detect(parameters); - t.stop(); - - time_ransac.push_back (t.time()); - nb_detected_ransac.push_back (ransac.shapes().size()); - nb_unassigned_ransac.push_back (ransac.number_of_unassigned_points() / double(points.size())); - -#if 0 - if (ransac.shapes().size() == 0) - { - std::cerr << "Detected 0 shapes with " << std::endl - << " * min points = " << min_points << std::endl - << " * epsilon = " << epsilon << std::endl - << " * cluster_epsilon = " << cluster_epsilon << std::endl - << " * normal_threshold = " << normal_threshold << std::endl; - - std::ofstream ofile("0shapes.ply", std::ios::binary); - CGAL::set_binary_mode (ofile); - CGAL::write_ply_points (ofile, points, - CGAL::parameters::point_map(Point_map()). - normal_map(Normal_map())); - ofile.close(); - exit(0); - } -#endif - - if (timer.time() > timeout) - { - nb_runs = run + 1; - break; - } - } - - std::cerr << "on " << nb_runs << " runs" << std::endl; - - - std::sort (time_ransac.begin(), time_ransac.end()); - std::sort (nb_detected_ransac.begin(), nb_detected_ransac.end()); - std::sort (nb_unassigned_ransac.begin(), nb_unassigned_ransac.end()); - std::sort (time_rg.begin(), time_rg.end()); - std::sort (nb_detected_rg.begin(), nb_detected_rg.end()); - std::sort (nb_unassigned_rg.begin(), nb_unassigned_rg.end()); - - std::cerr << " * Region Growing" << std::endl - << " - took between " << time_rg.front() << "s and " << time_rg.back() - << "s, median = " << time_rg[nb_runs / 2] << "s" << std::endl - << " - detected between " << nb_detected_rg.front() << " and " - << nb_detected_rg.back() << " planes (" << 100. * nb_detected_rg.front() / double(nb_planes) - << "% to " << 100. * nb_detected_rg.back() / double(nb_planes) << "%), median = " - << nb_detected_rg[nb_runs / 2] << " planes (" << 100. * nb_detected_rg[nb_runs / 2] / double(nb_planes) - << "%)" << std::endl - << " - left between " << 100. * nb_unassigned_rg.front() - << "% and " << 100. * nb_unassigned_rg.back() << "% of unassigned points, median = " - << 100. * nb_unassigned_rg[nb_runs / 2] << "%" << std::endl; - std::cerr << " * Efficient RANSAC" << std::endl - << " - took between " << time_ransac.front() << "s and " << time_ransac.back() - << "s, median = " << time_ransac[nb_runs / 2] << "s" << std::endl - << " - detected between " << nb_detected_ransac.front() << " and " - << nb_detected_ransac.back() << " planes (" << 100. * nb_detected_ransac.front() / double(nb_planes) - << "% to " << 100. * nb_detected_ransac.back() / double(nb_planes) << "%), median = " - << nb_detected_ransac[nb_runs / 2] << " planes (" << 100. * nb_detected_ransac[nb_runs / 2] / double(nb_planes) - << "%)" << std::endl - << " - left between " << 100. * nb_unassigned_ransac.front() - << "% and " << 100. * nb_unassigned_ransac.back() << "% of unassigned points, median = " - << 100. * nb_unassigned_ransac[nb_runs / 2] << "%" << std::endl; -} diff --git a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp index a194e9f43e9..85ee4de534f 100644 --- a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp +++ b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp @@ -1,6 +1,7 @@ #include #define CGAL_RANSAC_EXPERIMENTAL_FIXES +#define USE_WEIGHTED_LEVELS #include #include #include @@ -75,7 +76,8 @@ void test_copied_point_cloud (const Point_set& original_points, std::size_t nb) (CGAL::make_transform_iterator_from_property_map (original_points.begin(), Point_map()), CGAL::make_transform_iterator_from_property_map (original_points.end(), Point_map())); - std::cerr << "Ground truth = " << 6*nb*nb + 1 << " planes" << std::endl; + std::size_t ground_truth = 6*nb*nb+1; + std::cerr << "Ground truth = " << ground_truth << " planes" << std::endl; Point_set points; points.reserve (nb * nb * original_points.size()); @@ -116,6 +118,8 @@ void test_copied_point_cloud (const Point_set& original_points, std::size_t nb) t.stop(); std::cerr << "Region Growing = " << nb_detected << " planes (" << 1000 * t.time() << "ms)" << std::endl; + assert (nb_detected == ground_truth); + CGAL::Real_timer timer; double timeout = 120; // 2 minutes timeout timer.start(); @@ -151,6 +155,9 @@ void test_copied_point_cloud (const Point_set& original_points, std::size_t nb) << detected_ransac.front() << ";" << detected_ransac.back() << "], time[" << times_ransac.front() << ";" << times_ransac.back() << "])" << std::endl; + // RANSAC should at least detect 75% of shapes + assert (detected_ransac[detected_ransac.size() / ] > std::size_t(0.75 * ground_truth)); + #ifdef CGAL_TEST_RANSAC_PROTOTYPE { CGAL::Real_timer timer;