From f139720b8df1bf50d970c4c4a7cf60aa9c8eb03d Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Mon, 22 Jun 2015 00:04:31 +0200 Subject: [PATCH] added unit test for scenes accesses all points assigned to a shape retrieves the unassigned point range validates coverage requires cube.pwn --- .../CGAL/Shape_detection_3/Efficient_RANSAC.h | 2 + .../CMakeLists.txt | 1 + .../test_scene.cpp | 142 ++++++++++++++++++ .../test_sphere_connected_component.cpp | 14 +- 4 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 Point_set_shape_detection_3/test/Point_set_shape_detection_3/test_scene.cpp diff --git a/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC.h b/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC.h index ccb366a359d..d3d8b73bfe7 100644 --- a/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC.h +++ b/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC.h @@ -70,6 +70,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}. /// \cond SKIP_IN_MANUAL struct Filter_unassigned_points { + Filter_unassigned_points() : m_shape_index(dummy) {} Filter_unassigned_points(const std::vector &shapeIndex) : m_shape_index(shapeIndex) {} @@ -79,6 +80,7 @@ shape. The implementation follows \cgalCite{schnabel2007efficient}. else return true; // to prevent infinite incrementing } const std::vector& m_shape_index; + std::vector dummy; }; typedef boost::filter_iterator +#include +#include + +#include +#include +#include + + +template +bool test_scene() { + typedef typename K::FT FT; + typedef CGAL::Point_with_normal_3 Pwn; + typedef CGAL::Point_3 Point; + typedef CGAL::Vector_3 Vector; + typedef std::vector Pwn_vector; + typedef CGAL::Identity_property_map Point_map; + typedef CGAL::Normal_of_point_with_normal_pmap Normal_map; + + typedef CGAL::Shape_detection_3::Efficient_RANSAC_traits< + K, Pwn_vector, Point_map, Normal_map> Traits; + + typedef CGAL::Shape_detection_3::Efficient_RANSAC + Efficient_ransac; + + typedef typename Efficient_ransac::Point_index_range Point_index_range; + + typedef CGAL::Shape_detection_3::Plane Plane; + typedef CGAL::Shape_detection_3::Cone Cone; + typedef CGAL::Shape_detection_3::Cylinder Cylinder; + typedef CGAL::Shape_detection_3::Sphere Sphere; + typedef CGAL::Shape_detection_3::Torus Torus; + + Pwn_vector points; + + // Loads point set from a file. + // read_xyz_points_and_normals takes an OutputIterator for storing the points + // and a property map to store the normal vector with each point. + std::ifstream stream("cube.pwn"); + + if (!stream || + !CGAL::read_xyz_points_and_normals(stream, + std::back_inserter(points), + Normal_map())) + { + std::cerr << "Error: cannot read file cube.pwn" << std::endl; + return EXIT_FAILURE; + } + + + Efficient_ransac ransac; + + ransac.template add_shape_factory(); + + ransac.clear_shape_factories(); + + ransac.template add_shape_factory(); + ransac.template add_shape_factory(); + ransac.template add_shape_factory(); + ransac.template add_shape_factory(); + ransac.template add_shape_factory(); + + ransac.set_input(points); + + ransac.preprocess(); + + ransac.clear_octrees(); + + if (!ransac.detect()) { + std::cout << " aborted" << std::endl; + return false; + } + + typename Efficient_ransac::Shape_range shapes = ransac.shapes(); + + Efficient_ransac::Shape_range::iterator it = shapes.begin(); + + // Iterate through all shapes and access each point. + while (it != shapes.end()) { + boost::shared_ptr shape = *it; + + // Sums distances of points to detected shapes. + FT sum_distances = 0; + + // Iterates through point indices assigned to each detected shape. + std::vector::const_iterator + index_it = (*it)->indices_of_assigned_points().begin(); + + while (index_it != (*it)->indices_of_assigned_points().end()) { + + // Retrieves point + const Pwn &p = *(points.begin() + (*index_it)); + + // Adds Euclidean distance between point and shape. + sum_distances += CGAL::sqrt((*it)->squared_distance(p)); + + // Proceeds with next point. + index_it++; + } + + // Computes and prints average distance. + FT average_distance = sum_distances / shape->indices_of_assigned_points().size(); + + // Proceeds with next detected shape. + it++; + } + + // Check coverage. For this scene it should not fall below 85% + double coverage = double(points.size() - ransac.number_of_unassigned_points()) / double(points.size()); + if (coverage < 0.85) { + std::cout << " failed" << std::endl; + + return false; + } + + Point_index_range pts = ransac.indices_of_unassigned_points(); + + std::cout << " succeeded" << std::endl; + + return true; +} + + +int main() { + bool success = true; + + std::cout << "test_scene> "; + if (!test_scene >()) + success = false; + + std::cout << "test_scene> "; + if (!test_scene >()) + success = false; + + std::cout << "test_scene "; + if (!test_scene()) + success = false; + + return (success) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/Point_set_shape_detection_3/test/Point_set_shape_detection_3/test_sphere_connected_component.cpp b/Point_set_shape_detection_3/test/Point_set_shape_detection_3/test_sphere_connected_component.cpp index 203f1d6a5ad..2ad165f305d 100644 --- a/Point_set_shape_detection_3/test/Point_set_shape_detection_3/test_sphere_connected_component.cpp +++ b/Point_set_shape_detection_3/test/Point_set_shape_detection_3/test_sphere_connected_component.cpp @@ -13,13 +13,13 @@ bool test_sphere_connected_component() { const int NB_ROUNDS = 10; const int NB_POINTS = 2000; - typedef typename K::FT FT; - typedef typename CGAL::Point_with_normal_3 Pwn; - typedef typename CGAL::Point_3 Point; - typedef typename CGAL::Vector_3 Vector; - typedef std::vector Pwn_vector; - typedef typename CGAL::Identity_property_map Point_map; - typedef typename CGAL::Normal_of_point_with_normal_pmap Normal_map; + typedef K::FT FT; + typedef CGAL::Point_with_normal_3 Pwn; + typedef CGAL::Point_3 Point; + typedef CGAL::Vector_3 Vector; + typedef std::vector Pwn_vector; + typedef CGAL::Identity_property_map Point_map; + typedef CGAL::Normal_of_point_with_normal_pmap Normal_map; typedef CGAL::Shape_detection_3::Efficient_RANSAC_traits< K, Pwn_vector, Point_map, Normal_map> Traits;