cgal/Shape_detection/test/Shape_detection/test_efficient_RANSAC_scene...

164 lines
5.3 KiB
C++

#include "include/test_efficient_RANSAC_generators.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
#include <CGAL/Shape_regularization/regularize_planes.h>
#include <CGAL/Point_with_normal_3.h>
#include <CGAL/property_map.h>
template <class K>
bool test_scene(int argc, char** argv) {
typedef typename K::FT FT;
typedef CGAL::Point_with_normal_3<K> Pwn;
typedef std::vector<Pwn> Pwn_vector;
typedef CGAL::Identity_property_map<Pwn> Point_map;
typedef CGAL::Normal_of_point_with_normal_map<K> Normal_map;
typedef CGAL::Shape_detection::Efficient_RANSAC_traits<K, Pwn_vector, Point_map, Normal_map> Traits;
typedef CGAL::Shape_detection::Efficient_RANSAC<Traits> Efficient_ransac;
typedef typename Efficient_ransac::Point_index_range Point_index_range;
typedef CGAL::Shape_detection::Plane<Traits> Plane;
typedef CGAL::Shape_detection::Cone<Traits> Cone;
typedef CGAL::Shape_detection::Cylinder<Traits> Cylinder;
typedef CGAL::Shape_detection::Sphere<Traits> Sphere;
typedef CGAL::Shape_detection::Torus<Traits> Torus;
Pwn_vector points;
// Load point set from a file.
// read_points takes an OutputIterator for storing the points
// and a property map to store the normal vector with each point.
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("points_3/cube.pwn");
if (!CGAL::IO::read_points(filename, std::back_inserter(points),
CGAL::parameters::point_map(Point_map())
.normal_map(Normal_map())))
{
std::cerr << "Error: cannot read file cube.pwn" << std::endl;
return EXIT_FAILURE;
}
Efficient_ransac ransac;
ransac.template add_shape_factory<Cone>();
ransac.clear_shape_factories();
ransac.template add_shape_factory<Cone>();
ransac.template add_shape_factory<Cylinder>();
ransac.template add_shape_factory<Plane>();
ransac.template add_shape_factory<Sphere>();
ransac.template add_shape_factory<Torus>();
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();
typename Efficient_ransac::Shape_range::iterator it = shapes.begin();
FT average_distance = 0;
// Iterate through all shapes and access each point.
while (it != shapes.end()) {
std::shared_ptr<typename Efficient_ransac::Shape> shape = *it;
// Sum distances of points to detected shapes.
FT sum_distances = 0;
// Iterate through point indices assigned to each detected shape.
std::vector<std::size_t>::const_iterator
index_it = (*it)->indices_of_assigned_points().begin();
while (index_it != (*it)->indices_of_assigned_points().end()) {
// Retrieve point.
const Pwn &p = *(points.begin() + (*index_it));
// Add Euclidean distance between point and shape.
sum_distances += CGAL::sqrt((*it)->squared_distance(p));
// Proceed with next point.
index_it++;
}
// Compute average distance.
average_distance += sum_distances / shape->indices_of_assigned_points().size();
// Proceed with next detected shape.
it++;
}
// Check coverage. For this scene it should not fall below 75%.
double coverage = double(points.size() - ransac.number_of_unassigned_points()) / double(points.size());
if (coverage < 0.75) {
std::cout << " failed (coverage = " << coverage << " < 0.75)" << std::endl;
return false;
}
// Check average distance. It should not lie above 0.02.
average_distance = average_distance / shapes.size();
std::cout << average_distance << " " << std::endl;
if (average_distance > 0.02) {
std::cout << " failed" << std::endl;
return false;
}
// Test regularization
typename Efficient_ransac::Plane_range planes = ransac.planes();
CGAL::Shape_regularization::Planes::
regularize_planes(
planes,
CGAL::Shape_detection::Plane_map<Traits>(),
points,
Point_map(),
CGAL::parameters::plane_index_map(
CGAL::Shape_detection::Point_to_shape_index_map<Traits>(points, planes)).
regularize_parallelism(true).
regularize_orthogonality(true).
regularize_coplanarity(true).
regularize_axis_symmetry(true).
maximum_angle(FT(50)).
maximum_offset(FT(1) / FT(100)));
Point_index_range pts = ransac.indices_of_unassigned_points();
std::cout << " succeeded" << std::endl;
return true;
}
int main(int argc, char** argv) {
bool success = true;
std::cout << "test_scene<CGAL::Simple_cartesian<float>> ";
if (!test_scene<CGAL::Simple_cartesian<float> >(argc, argv))
success = false;
// std::cout << "test_scene<CGAL::Simple_cartesian<double>> ";
// if (!test_scene<CGAL::Simple_cartesian<double> >(argc, argv))
// success = false;
//
// std::cout << "test_scene<CGAL::Exact_predicates_inexact_constructions_kernel> ";
// if (!test_scene<CGAL::Exact_predicates_inexact_constructions_kernel>(argc, argv))
// success = false;
return (success) ? EXIT_SUCCESS : EXIT_FAILURE;
}